LCOV - code coverage report
Current view: top level - library/spdm_common_lib - libspdm_com_context_data.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 45.5 % 1594 726
Test Date: 2025-06-29 08:09:00 Functions: 86.7 % 75 65

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2021-2025 DMTF. All rights reserved.
       4              :  *  License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
       5              :  **/
       6              : 
       7              : #include "internal/libspdm_common_lib.h"
       8              : #include "internal/libspdm_secured_message_lib.h"
       9              : #include "internal/libspdm_fips_lib.h"
      10              : 
      11              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
      12              : /* first section */
      13        68131 : uint32_t libspdm_get_scratch_buffer_secure_message_offset(libspdm_context_t *spdm_context) {
      14        68131 :     return 0;
      15              : }
      16              : 
      17       419934 : uint32_t libspdm_get_scratch_buffer_secure_message_capacity(libspdm_context_t *spdm_context) {
      18       419934 :     return spdm_context->local_context.capability.max_spdm_msg_size +
      19       839868 :            spdm_context->local_context.capability.transport_header_size +
      20       419934 :            spdm_context->local_context.capability.transport_tail_size;
      21              : }
      22              : 
      23              : /* second section */
      24           38 : uint32_t libspdm_get_scratch_buffer_large_message_offset(libspdm_context_t *spdm_context) {
      25           38 :     return libspdm_get_scratch_buffer_secure_message_capacity(spdm_context);
      26              : }
      27              : 
      28       351787 : uint32_t libspdm_get_scratch_buffer_large_message_capacity(libspdm_context_t *spdm_context) {
      29       351787 :     return spdm_context->local_context.capability.max_spdm_msg_size;
      30              : }
      31              : #endif
      32              : 
      33              : /* third section */
      34       201976 : uint32_t libspdm_get_scratch_buffer_sender_receiver_offset(libspdm_context_t *spdm_context) {
      35       201976 :     return 0 +
      36              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
      37              :            libspdm_get_scratch_buffer_secure_message_capacity(spdm_context) +
      38       201976 :            libspdm_get_scratch_buffer_large_message_capacity(spdm_context) +
      39              : #endif
      40              :            0;
      41              : }
      42              : 
      43       283595 : uint32_t libspdm_get_scratch_buffer_sender_receiver_capacity(libspdm_context_t *spdm_context) {
      44       283595 :     return spdm_context->local_context.capability.max_spdm_msg_size +
      45       567190 :            spdm_context->local_context.capability.transport_header_size +
      46       283595 :            spdm_context->local_context.capability.transport_tail_size;
      47              : }
      48              : 
      49              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
      50              : /* fourth section */
      51        12751 : uint32_t libspdm_get_scratch_buffer_large_sender_receiver_offset(libspdm_context_t *spdm_context) {
      52        12751 :     return libspdm_get_scratch_buffer_secure_message_capacity(spdm_context) +
      53        25502 :            libspdm_get_scratch_buffer_large_message_capacity(spdm_context) +
      54        12751 :            libspdm_get_scratch_buffer_sender_receiver_capacity(spdm_context);
      55              : }
      56              : 
      57       147237 : uint32_t libspdm_get_scratch_buffer_large_sender_receiver_capacity(libspdm_context_t *spdm_context)
      58              : {
      59       147237 :     return spdm_context->local_context.capability.max_spdm_msg_size +
      60       294474 :            spdm_context->local_context.capability.transport_header_size +
      61       147237 :            spdm_context->local_context.capability.transport_tail_size;
      62              : }
      63              : #endif
      64              : 
      65              : /* fifth section */
      66          103 : uint32_t libspdm_get_scratch_buffer_last_spdm_request_offset(libspdm_context_t *spdm_context) {
      67          103 :     return 0 +
      68              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
      69          103 :            libspdm_get_scratch_buffer_secure_message_capacity(spdm_context) +
      70          103 :            libspdm_get_scratch_buffer_large_message_capacity(spdm_context) +
      71              : #endif
      72          103 :            libspdm_get_scratch_buffer_sender_receiver_capacity(spdm_context) +
      73              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
      74          103 :            libspdm_get_scratch_buffer_large_sender_receiver_capacity(spdm_context) +
      75              : #endif
      76              :            0;
      77              : }
      78              : 
      79       276120 : uint32_t libspdm_get_scratch_buffer_last_spdm_request_capacity(libspdm_context_t *spdm_context) {
      80       276120 :     return spdm_context->local_context.capability.max_spdm_msg_size;
      81              : }
      82              : 
      83              : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
      84              : /* sixth section */
      85          103 : uint32_t libspdm_get_scratch_buffer_cache_spdm_request_offset(libspdm_context_t *spdm_context) {
      86          103 :     return 0 +
      87              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
      88          103 :            libspdm_get_scratch_buffer_secure_message_capacity(spdm_context) +
      89          103 :            libspdm_get_scratch_buffer_large_message_capacity(spdm_context) +
      90              : #endif
      91          103 :            libspdm_get_scratch_buffer_sender_receiver_capacity(spdm_context) +
      92              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
      93          103 :            libspdm_get_scratch_buffer_large_sender_receiver_capacity(spdm_context) +
      94              : #endif
      95          103 :            libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context) +
      96              :            0;
      97              : }
      98              : 
      99       273483 : uint32_t libspdm_get_scratch_buffer_cache_spdm_request_capacity(libspdm_context_t *spdm_context) {
     100       273483 :     return spdm_context->local_context.capability.max_spdm_msg_size;
     101              : }
     102              : #endif
     103              : 
     104              : /* combination */
     105       136832 : uint32_t libspdm_get_scratch_buffer_capacity(libspdm_context_t *spdm_context) {
     106       136832 :     return 0 +
     107              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
     108       136832 :            libspdm_get_scratch_buffer_secure_message_capacity(spdm_context) +
     109       136832 :            libspdm_get_scratch_buffer_large_message_capacity(spdm_context) +
     110              : #endif
     111       136832 :            libspdm_get_scratch_buffer_sender_receiver_capacity(spdm_context) +
     112              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
     113       136832 :            libspdm_get_scratch_buffer_large_sender_receiver_capacity(spdm_context) +
     114              : #endif
     115       136832 :            libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context) +
     116              : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
     117       136832 :            libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context) +
     118              : #endif
     119              :            0;
     120              : }
     121              : 
     122              : /**
     123              :  * Returns if an SPDM data_type requires session info.
     124              :  *
     125              :  * @param data_type  SPDM data type.
     126              :  *
     127              :  * @retval true  session info is required.
     128              :  * @retval false session info is not required.
     129              :  **/
     130           61 : static bool need_session_info_for_data(libspdm_data_type_t data_type)
     131              : {
     132           61 :     switch (data_type) {
     133            0 :     case LIBSPDM_DATA_SESSION_USE_PSK:
     134              :     case LIBSPDM_DATA_SESSION_MUT_AUTH_REQUESTED:
     135              :     case LIBSPDM_DATA_SESSION_END_SESSION_ATTRIBUTES:
     136              :     case LIBSPDM_DATA_SESSION_POLICY:
     137              :     case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_RSP_DIR:
     138              :     case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_REQ_DIR:
     139              :     case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_ENDIAN:
     140            0 :         return true;
     141           61 :     default:
     142           61 :         return false;
     143              :     }
     144              : }
     145              : 
     146              : /**
     147              :  * Set an SPDM context data.
     148              :  *
     149              :  * @param  spdm_context                  A pointer to the SPDM context.
     150              :  * @param  data_type                     Type of the SPDM context data.
     151              :  * @param  parameter                    Type specific parameter of the SPDM context data.
     152              :  * @param  data                         A pointer to the SPDM context data.
     153              :  * @param  data_size                     size in bytes of the SPDM context data.
     154              :  *
     155              :  * @retval RETURN_SUCCESS               The SPDM context data is set successfully.
     156              :  * @retval RETURN_INVALID_PARAMETER     The data is NULL or the data_type is zero.
     157              :  * @retval RETURN_UNSUPPORTED           The data_type is unsupported.
     158              :  * @retval RETURN_ACCESS_DENIED         The data_type cannot be set.
     159              :  * @retval RETURN_NOT_READY             data is not ready to set.
     160              :  **/
     161           19 : libspdm_return_t libspdm_set_data(void *spdm_context, libspdm_data_type_t data_type,
     162              :                                   const libspdm_data_parameter_t *parameter, const void *data,
     163              :                                   size_t data_size)
     164              : {
     165              :     libspdm_context_t *context;
     166              :     uint32_t session_id;
     167              :     uint32_t data32;
     168              :     libspdm_session_info_t *session_info;
     169              :     uint8_t slot_id;
     170              :     uint8_t mut_auth_requested;
     171              :     uint8_t root_cert_index;
     172              :     uint16_t data16;
     173              : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT) && LIBSPDM_CERT_PARSE_SUPPORT
     174              :     bool status;
     175              :     const uint8_t *cert_buffer;
     176              :     size_t cert_buffer_size;
     177              : #endif
     178              : 
     179           19 :     if (spdm_context == NULL || data == NULL || data_type >= LIBSPDM_DATA_MAX) {
     180            0 :         return LIBSPDM_STATUS_INVALID_PARAMETER;
     181              :     }
     182              : 
     183           19 :     context = spdm_context;
     184              : 
     185           19 :     if (need_session_info_for_data(data_type)) {
     186            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_SESSION) {
     187            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     188              :         }
     189            0 :         session_id = libspdm_read_uint32(parameter->additional_data);
     190            0 :         session_info = libspdm_get_session_info_via_session_id(context, session_id);
     191            0 :         if (session_info == NULL) {
     192            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     193              :         }
     194              :     } else {
     195           19 :         session_info = NULL;
     196              :     }
     197              : 
     198           19 :     switch (data_type) {
     199            0 :     case LIBSPDM_DATA_SPDM_VERSION:
     200            0 :         LIBSPDM_ASSERT (data_size <= sizeof(spdm_version_number_t) * SPDM_MAX_VERSION_COUNT);
     201            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     202              :             /* Only have one connected version */
     203            0 :             LIBSPDM_ASSERT (data_size == sizeof(spdm_version_number_t));
     204            0 :             libspdm_copy_mem(&(context->connection_info.version),
     205              :                              sizeof(context->connection_info.version),
     206              :                              data,
     207              :                              sizeof(spdm_version_number_t));
     208            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     209            0 :             context->local_context.version.spdm_version_count =
     210            0 :                 (uint8_t)(data_size / sizeof(spdm_version_number_t));
     211            0 :             libspdm_copy_mem(context->local_context.version.spdm_version,
     212              :                              sizeof(context->local_context.version.spdm_version),
     213              :                              data,
     214            0 :                              context->local_context.version.spdm_version_count *
     215              :                              sizeof(spdm_version_number_t));
     216              :         } else {
     217            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     218              :         }
     219            0 :         break;
     220            0 :     case LIBSPDM_DATA_SECURED_MESSAGE_VERSION:
     221            0 :         LIBSPDM_ASSERT (data_size <=
     222              :                         sizeof(spdm_version_number_t) * SECURED_SPDM_MAX_VERSION_COUNT);
     223            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     224              :             /* Only have one connected version */
     225            0 :             LIBSPDM_ASSERT (data_size == sizeof(spdm_version_number_t));
     226            0 :             libspdm_copy_mem(&(context->connection_info.secured_message_version),
     227              :                              sizeof(context->connection_info.secured_message_version),
     228              :                              data,
     229              :                              sizeof(spdm_version_number_t));
     230            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     231              :             context->local_context.secured_message_version
     232            0 :             .spdm_version_count = (uint8_t)(data_size / sizeof(spdm_version_number_t));
     233            0 :             libspdm_copy_mem(context->local_context
     234            0 :                              .secured_message_version.spdm_version,
     235              :                              sizeof(context->local_context
     236              :                                     .secured_message_version.spdm_version),
     237              :                              data,
     238            0 :                              context->local_context.secured_message_version.
     239              :                              spdm_version_count * sizeof(spdm_version_number_t));
     240              :         } else {
     241            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     242              :         }
     243            0 :         break;
     244            0 :     case LIBSPDM_DATA_CAPABILITY_FLAGS:
     245            0 :         if (data_size != sizeof(uint32_t)) {
     246            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     247              :         }
     248              : 
     249            0 :         data32 = libspdm_read_uint32((const uint8_t *)data);
     250              : 
     251            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     252              :             #if !(LIBSPDM_ENABLE_CAPABILITY_CERT_CAP)
     253              :             LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0);
     254              :             #endif /* !LIBSPDM_ENABLE_CAPABILITY_CERT_CAP */
     255              : 
     256              :             #if !(LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP)
     257              :             LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) == 0);
     258              :             #endif /* !LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP */
     259              : 
     260              :             #if !(LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP)
     261              :             LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) == 0);
     262              :             #endif /* !LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP */
     263              : 
     264              :             #if !(LIBSPDM_ENABLE_CAPABILITY_MEL_CAP)
     265              :             LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEL_CAP) == 0);
     266              :             #endif /* !LIBSPDM_ENABLE_CAPABILITY_MEL_CAP */
     267              : 
     268              :             #if !(LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP)
     269              :             LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == 0);
     270              :             #endif /* !LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP */
     271              : 
     272              :             #if !(LIBSPDM_ENABLE_CAPABILITY_PSK_CAP)
     273              :             LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) == 0);
     274              :             #endif /* !LIBSPDM_ENABLE_CAPABILITY_PSK_CAP */
     275              : 
     276              :             #if !(LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP)
     277              :             LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP) == 0);
     278              :             #endif /* !LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP */
     279              : 
     280            0 :             context->local_context.capability.flags = data32;
     281            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     282            0 :             context->connection_info.capability.flags = data32;
     283              :         } else {
     284            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     285              :         }
     286            0 :         break;
     287            0 :     case LIBSPDM_DATA_CAPABILITY_CT_EXPONENT:
     288            0 :         if (data_size != sizeof(uint8_t)) {
     289            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     290              :         }
     291            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     292            0 :             context->connection_info.capability.ct_exponent = *(const uint8_t *)data;
     293            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     294            0 :             context->local_context.capability.ct_exponent = *(const uint8_t *)data;
     295              :         } else {
     296            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     297              :         }
     298            0 :         break;
     299            0 :     case LIBSPDM_DATA_CAPABILITY_RTT_US:
     300            0 :         if (data_size != sizeof(uint64_t)) {
     301            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     302              :         }
     303            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     304            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     305              :         }
     306            0 :         context->local_context.capability.rtt = libspdm_read_uint64((const uint8_t *)data);
     307            0 :         break;
     308            0 :     case LIBSPDM_DATA_CAPABILITY_MAX_SPDM_MSG_SIZE:
     309            0 :         if (data_size != sizeof(uint32_t)) {
     310            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     311              :         }
     312              :         /* The local max_spdm_msg_size is set by libspdm_register_transport_layer_func.
     313              :          * Only the connection's max_spdm_msg_size is settable here. */
     314            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     315            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     316              :         }
     317            0 :         data32 = libspdm_read_uint32((const uint8_t *)data);
     318            0 :         LIBSPDM_ASSERT (data32 >= SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12);
     319            0 :         context->connection_info.capability.max_spdm_msg_size = data32;
     320            0 :         break;
     321            0 :     case LIBSPDM_DATA_MEASUREMENT_SPEC:
     322            0 :         if (data_size != sizeof(uint8_t)) {
     323            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     324              :         }
     325            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     326            0 :             context->connection_info.algorithm.measurement_spec = *(const uint8_t *)data;
     327            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     328            0 :             context->local_context.algorithm.measurement_spec = *(const uint8_t *)data;
     329              :         } else {
     330            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     331              :         }
     332            0 :         break;
     333            0 :     case LIBSPDM_DATA_MEASUREMENT_HASH_ALGO:
     334            0 :         if (data_size != sizeof(uint32_t)) {
     335            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     336              :         }
     337            0 :         data32 = libspdm_read_uint32((const uint8_t *)data);
     338            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     339            0 :             context->connection_info.algorithm.measurement_hash_algo = data32;
     340            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     341            0 :             context->local_context.algorithm.measurement_hash_algo = data32;
     342              :         } else {
     343            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     344              :         }
     345            0 :         break;
     346            0 :     case LIBSPDM_DATA_BASE_ASYM_ALGO:
     347            0 :         if (data_size != sizeof(uint32_t)) {
     348            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     349              :         }
     350            0 :         data32 = libspdm_read_uint32((const uint8_t *)data);
     351            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     352            0 :             context->connection_info.algorithm.base_asym_algo = data32;
     353            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     354            0 :             context->local_context.algorithm.base_asym_algo = data32;
     355              :         } else {
     356            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     357              :         }
     358            0 :         break;
     359            0 :     case LIBSPDM_DATA_BASE_HASH_ALGO:
     360            0 :         if (data_size != sizeof(uint32_t)) {
     361            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     362              :         }
     363            0 :         data32 = libspdm_read_uint32((const uint8_t *)data);
     364            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     365            0 :             context->connection_info.algorithm.base_hash_algo = data32;
     366            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     367            0 :             context->local_context.algorithm.base_hash_algo = data32;
     368              :         } else {
     369            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     370              :         }
     371            0 :         break;
     372            0 :     case LIBSPDM_DATA_DHE_NAME_GROUP:
     373            0 :         if (data_size != sizeof(uint16_t)) {
     374            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     375              :         }
     376            0 :         data16 = libspdm_read_uint16((const uint8_t *)data);
     377            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     378            0 :             context->connection_info.algorithm.dhe_named_group = data16;
     379            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     380            0 :             context->local_context.algorithm.dhe_named_group = data16;
     381              :         } else {
     382            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     383              :         }
     384            0 :         break;
     385            0 :     case LIBSPDM_DATA_AEAD_CIPHER_SUITE:
     386            0 :         if (data_size != sizeof(uint16_t)) {
     387            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     388              :         }
     389            0 :         data16 = libspdm_read_uint16((const uint8_t *)data);
     390            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     391            0 :             context->connection_info.algorithm.aead_cipher_suite = data16;
     392            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     393            0 :             context->local_context.algorithm.aead_cipher_suite = data16;
     394              :         } else {
     395            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     396              :         }
     397            0 :         break;
     398            0 :     case LIBSPDM_DATA_REQ_BASE_ASYM_ALG:
     399            0 :         if (data_size != sizeof(uint16_t)) {
     400            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     401              :         }
     402            0 :         data16 = libspdm_read_uint16((const uint8_t *)data);
     403            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     404            0 :             context->connection_info.algorithm.req_base_asym_alg = data16;
     405            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     406            0 :             context->local_context.algorithm.req_base_asym_alg = data16;
     407              :         } else {
     408            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     409              :         }
     410            0 :         break;
     411            0 :     case LIBSPDM_DATA_KEY_SCHEDULE:
     412            0 :         if (data_size != sizeof(uint16_t)) {
     413            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     414              :         }
     415            0 :         data16 = libspdm_read_uint16((const uint8_t *)data);
     416            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     417            0 :             context->connection_info.algorithm.key_schedule = data16;
     418            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     419            0 :             context->local_context.algorithm.key_schedule = data16;
     420              :         } else {
     421            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     422              :         }
     423            0 :         break;
     424            0 :     case LIBSPDM_DATA_OTHER_PARAMS_SUPPORT:
     425            0 :         if (data_size != sizeof(uint8_t)) {
     426            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     427              :         }
     428            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     429            0 :             context->connection_info.algorithm.other_params_support = *(const uint8_t *)data;
     430            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     431            0 :             context->local_context.algorithm.other_params_support = *(const uint8_t *)data;
     432              :         } else {
     433            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     434              :         }
     435            0 :         break;
     436            0 :     case LIBSPDM_DATA_MEL_SPEC:
     437            0 :         if (data_size != sizeof(uint8_t)) {
     438            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     439              :         }
     440            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     441            0 :             context->connection_info.algorithm.mel_spec = *(const uint8_t *)data;
     442            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     443            0 :             context->local_context.algorithm.mel_spec = *(const uint8_t *)data;
     444              :         } else {
     445            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     446              :         }
     447            0 :         break;
     448            0 :     case LIBSPDM_DATA_CONNECTION_STATE:
     449            0 :         if (data_size != sizeof(libspdm_connection_state_t)) {
     450            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     451              :         }
     452            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     453            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     454              :         }
     455            0 :         context->connection_info.connection_state = libspdm_read_uint32((const uint8_t *)data);
     456            0 :         break;
     457            0 :     case LIBSPDM_DATA_RESPONSE_STATE:
     458            0 :         if (data_size != sizeof(libspdm_response_state_t)) {
     459            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     460              :         }
     461            0 :         context->response_state = libspdm_read_uint32((const uint8_t *)data);
     462            0 :         break;
     463            2 :     case LIBSPDM_DATA_PEER_PUBLIC_ROOT_CERT:
     464            2 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     465            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     466              :         }
     467            2 :         root_cert_index = 0;
     468           11 :         while (context->local_context.peer_root_cert_provision[root_cert_index] != NULL) {
     469           10 :             root_cert_index++;
     470           10 :             if (root_cert_index >= LIBSPDM_MAX_ROOT_CERT_SUPPORT) {
     471            1 :                 return LIBSPDM_STATUS_BUFFER_FULL;
     472              :             }
     473              :         }
     474            1 :         context->local_context.peer_root_cert_provision_size[root_cert_index] = data_size;
     475            1 :         context->local_context.peer_root_cert_provision[root_cert_index] = data;
     476            1 :         break;
     477            0 :     case LIBSPDM_DATA_LOCAL_PUBLIC_CERT_CHAIN:
     478            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     479            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     480              :         }
     481            0 :         slot_id = parameter->additional_data[0];
     482            0 :         if (slot_id >= SPDM_MAX_SLOT_COUNT) {
     483            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     484              :         }
     485            0 :         context->local_context.local_cert_chain_provision_size[slot_id] = data_size;
     486            0 :         context->local_context.local_cert_chain_provision[slot_id] = data;
     487            0 :         break;
     488            0 :     case LIBSPDM_DATA_LOCAL_SUPPORTED_SLOT_MASK:
     489            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     490            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     491              :         }
     492            0 :         if (data_size != sizeof(uint8_t)) {
     493            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     494              :         }
     495            0 :         context->local_context.local_supported_slot_mask = *(const uint8_t *)data;
     496            0 :         break;
     497            0 :     case LIBSPDM_DATA_LOCAL_KEY_PAIR_ID:
     498            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     499            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     500              :         }
     501            0 :         slot_id = parameter->additional_data[0];
     502            0 :         if (slot_id >= SPDM_MAX_SLOT_COUNT) {
     503            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     504              :         }
     505            0 :         if (data_size != sizeof(spdm_key_pair_id_t)) {
     506            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     507              :         }
     508            0 :         context->local_context.local_key_pair_id[slot_id] = *(const spdm_key_pair_id_t *)data;
     509            0 :         break;
     510            0 :     case LIBSPDM_DATA_LOCAL_CERT_INFO:
     511            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     512            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     513              :         }
     514            0 :         slot_id = parameter->additional_data[0];
     515            0 :         if (slot_id >= SPDM_MAX_SLOT_COUNT) {
     516            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     517              :         }
     518            0 :         if (data_size != sizeof(spdm_certificate_info_t)) {
     519            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     520              :         }
     521            0 :         context->local_context.local_cert_info[slot_id] = *(const spdm_certificate_info_t *)data;
     522            0 :         break;
     523            0 :     case LIBSPDM_DATA_LOCAL_KEY_USAGE_BIT_MASK:
     524            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     525            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     526              :         }
     527            0 :         slot_id = parameter->additional_data[0];
     528            0 :         if (slot_id >= SPDM_MAX_SLOT_COUNT) {
     529            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     530              :         }
     531            0 :         if (data_size != sizeof(spdm_key_usage_bit_mask_t)) {
     532            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     533              :         }
     534            0 :         context->local_context.local_key_usage_bit_mask[slot_id] =
     535            0 :             libspdm_read_uint16((const uint8_t *)data);
     536            0 :         break;
     537            3 :     case LIBSPDM_DATA_PEER_USED_CERT_CHAIN_BUFFER:
     538            3 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     539            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     540              :         }
     541            3 :         slot_id = parameter->additional_data[0];
     542            3 :         if (slot_id >= SPDM_MAX_SLOT_COUNT) {
     543            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     544              :         }
     545            3 :         if (data_size > LIBSPDM_MAX_CERT_CHAIN_SIZE) {
     546            0 :             return LIBSPDM_STATUS_BUFFER_FULL;
     547              :         }
     548            3 :         context->connection_info.peer_used_cert_chain_slot_id = slot_id;
     549              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     550              :         context->connection_info.peer_used_cert_chain[slot_id].buffer_size = data_size;
     551              :         libspdm_copy_mem(context->connection_info.peer_used_cert_chain[slot_id].buffer,
     552              :                          sizeof(context->connection_info.peer_used_cert_chain[slot_id].buffer),
     553              :                          data, data_size);
     554              : #else
     555              : #if LIBSPDM_CERT_PARSE_SUPPORT
     556            3 :         status = libspdm_hash_all(
     557              :             context->connection_info.algorithm.base_hash_algo,
     558              :             data, data_size,
     559            3 :             context->connection_info.peer_used_cert_chain[slot_id].buffer_hash);
     560            3 :         if (!status) {
     561            0 :             return LIBSPDM_STATUS_CRYPTO_ERROR;
     562              :         }
     563              : 
     564            6 :         context->connection_info.peer_used_cert_chain[slot_id].buffer_hash_size =
     565            3 :             libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo);
     566              : 
     567              :         /*process the SPDM cert header and hash*/
     568            3 :         data = (const uint8_t *)data + sizeof(spdm_cert_chain_t) +
     569            3 :                libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo);
     570            3 :         data_size = data_size -
     571              :                     (sizeof(spdm_cert_chain_t) +
     572            3 :                      libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo));
     573              : 
     574              :         /* Get leaf cert from cert chain */
     575            3 :         status = libspdm_x509_get_cert_from_cert_chain(data, data_size, -1,
     576              :                                                        &cert_buffer, &cert_buffer_size);
     577            3 :         if (!status) {
     578            0 :             return LIBSPDM_STATUS_CRYPTO_ERROR;
     579              :         }
     580              : 
     581            3 :         status = false;
     582              : #if (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT)
     583            3 :         if (!status) {
     584            3 :             status = libspdm_rsa_get_public_key_from_x509(
     585              :                 cert_buffer, cert_buffer_size,
     586            3 :                 &context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key);
     587              :         }
     588              : #endif
     589              : #if LIBSPDM_ECDSA_SUPPORT
     590            3 :         if (!status) {
     591            3 :             status = libspdm_ec_get_public_key_from_x509(
     592              :                 cert_buffer, cert_buffer_size,
     593            3 :                 &context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key);
     594              :         }
     595              : #endif
     596              : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
     597              :         if (!status) {
     598              :             status = libspdm_ecd_get_public_key_from_x509(
     599              :                 cert_buffer, cert_buffer_size,
     600              :                 &context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key);
     601              :         }
     602              : #endif
     603              : #if LIBSPDM_SM2_DSA_SUPPORT
     604              :         if (!status) {
     605              :             status = libspdm_sm2_get_public_key_from_x509(
     606              :                 cert_buffer, cert_buffer_size,
     607              :                 &context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key);
     608              :         }
     609              : #endif
     610            3 :         if (!status) {
     611            0 :             return LIBSPDM_STATUS_INVALID_CERT;
     612              :         }
     613              : #else
     614              :         LIBSPDM_ASSERT (false);
     615              : #endif /* LIBSPDM_CERT_PARSE_SUPPORT */
     616              : #endif /* LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT */
     617            3 :         break;
     618            0 :     case LIBSPDM_DATA_PEER_PUBLIC_KEY:
     619            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     620            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     621              :         }
     622            0 :         context->local_context.peer_public_key_provision_size = data_size;
     623            0 :         context->local_context.peer_public_key_provision = data;
     624            0 :         break;
     625            0 :     case LIBSPDM_DATA_LOCAL_PUBLIC_KEY:
     626            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     627            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     628              :         }
     629            0 :         context->local_context.local_public_key_provision_size = data_size;
     630            0 :         context->local_context.local_public_key_provision = data;
     631            0 :         break;
     632            0 :     case LIBSPDM_DATA_BASIC_MUT_AUTH_REQUESTED:
     633            0 :         if (data_size != sizeof(bool)) {
     634            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     635              :         }
     636            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     637            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     638              :         }
     639            0 :         mut_auth_requested = *(const uint8_t *)data;
     640            0 :         if (((mut_auth_requested != 0) && (mut_auth_requested != 1))) {
     641            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     642              :         }
     643            0 :         context->local_context.basic_mut_auth_requested = mut_auth_requested;
     644            0 :         context->encap_context.request_id = 0;
     645            0 :         slot_id = parameter->additional_data[0];
     646            0 :         if ((slot_id >= SPDM_MAX_SLOT_COUNT) && (slot_id != 0xFF)) {
     647            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     648              :         }
     649            0 :         context->encap_context.req_slot_id = slot_id;
     650              : 
     651              :         #if LIBSPDM_DEBUG_PRINT_ENABLE
     652            0 :         if (mut_auth_requested) {
     653            0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
     654              :                            "Basic mutual authentication is a deprecated feature.\n"));
     655              :         }
     656              :         #endif /* LIBSPDM_DEBUG_PRINT_ENABLE */
     657            0 :         break;
     658            0 :     case LIBSPDM_DATA_MUT_AUTH_REQUESTED:
     659            0 :         if (data_size != sizeof(uint8_t)) {
     660            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     661              :         }
     662            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     663            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     664              :         }
     665            0 :         mut_auth_requested = *(const uint8_t *)data;
     666            0 :         if (((mut_auth_requested != 0) &&
     667              :              (mut_auth_requested !=
     668            0 :               SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED) &&
     669              :              (mut_auth_requested !=
     670            0 :               SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_ENCAP_REQUEST) &&
     671              :              (mut_auth_requested !=
     672              :               SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_GET_DIGESTS))) {
     673            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     674              :         }
     675            0 :         context->local_context.mut_auth_requested = mut_auth_requested;
     676            0 :         context->encap_context.request_id = 0;
     677            0 :         slot_id = parameter->additional_data[0];
     678            0 :         if ((slot_id >= SPDM_MAX_SLOT_COUNT) && (slot_id != 0xFF)) {
     679            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     680              :         }
     681            0 :         context->encap_context.req_slot_id = slot_id;
     682            0 :         break;
     683            0 :     case LIBSPDM_DATA_MANDATORY_MUT_AUTH:
     684            0 :         if (data_size != sizeof(bool)) {
     685            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     686              :         }
     687            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     688            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     689              :         }
     690            0 :         context->local_context.mandatory_mut_auth = *(const bool *)data;
     691            0 :         break;
     692            0 :     case LIBSPDM_DATA_HEARTBEAT_PERIOD:
     693            0 :         if (data_size != sizeof(uint8_t)) {
     694            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     695              :         }
     696            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     697            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     698              :         }
     699            0 :         context->local_context.heartbeat_period = *(const uint8_t *)data;
     700            0 :         break;
     701            4 :     case LIBSPDM_DATA_APP_CONTEXT_DATA:
     702            4 :         if (data_size != sizeof(void *) || *(void *const *)data == NULL) {
     703            2 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     704              :         }
     705            2 :         context->app_context_data_ptr = *(void *const *)data;
     706            2 :         break;
     707            0 :     case LIBSPDM_DATA_HANDLE_ERROR_RETURN_POLICY:
     708            0 :         if (data_size != sizeof(uint8_t)) {
     709            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     710              :         }
     711            0 :         context->handle_error_return_policy = *(const uint8_t *)data;
     712            0 :         break;
     713            0 :     case LIBSPDM_DATA_VCA_CACHE:
     714            0 :         if (data_size > sizeof(context->transcript.message_a.buffer)) {
     715            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     716              :         }
     717            0 :         context->transcript.message_a.buffer_size = data_size;
     718            0 :         libspdm_copy_mem(context->transcript.message_a.buffer,
     719              :                          sizeof(context->transcript.message_a.buffer),
     720              :                          data, data_size);
     721            0 :         break;
     722            0 :     case LIBSPDM_DATA_IS_REQUESTER:
     723            0 :         if (data_size != sizeof(bool)) {
     724            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     725              :         }
     726            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     727            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     728              :         }
     729            0 :         context->local_context.is_requester = *(const bool *)data;
     730            0 :         break;
     731            0 :     case LIBSPDM_DATA_REQUEST_RETRY_TIMES:
     732            0 :         if (data_size != sizeof(uint8_t)) {
     733            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     734              :         }
     735            0 :         context->retry_times = *(const uint8_t *)data;
     736            0 :         break;
     737            0 :     case LIBSPDM_DATA_REQUEST_RETRY_DELAY_TIME:
     738            0 :         if (data_size != sizeof(uint64_t)) {
     739            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     740              :         }
     741            0 :         context->retry_delay_time = *(const uint64_t *)data;
     742            0 :         break;
     743            5 :     case LIBSPDM_DATA_MAX_DHE_SESSION_COUNT:
     744            5 :         if (data_size != sizeof(uint32_t)) {
     745            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     746              :         }
     747            5 :         if (*(const uint32_t *)data > LIBSPDM_MAX_SESSION_COUNT - context->max_psk_session_count) {
     748            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     749              :         }
     750            5 :         context->max_dhe_session_count = *(const uint32_t *)data;
     751            5 :         break;
     752            5 :     case LIBSPDM_DATA_MAX_PSK_SESSION_COUNT:
     753            5 :         if (data_size != sizeof(uint32_t)) {
     754            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     755              :         }
     756            5 :         if (*(const uint32_t *)data > LIBSPDM_MAX_SESSION_COUNT - context->max_dhe_session_count) {
     757            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     758              :         }
     759            5 :         context->max_psk_session_count = *(const uint32_t *)data;
     760            5 :         break;
     761            0 :     case LIBSPDM_DATA_MAX_SPDM_SESSION_SEQUENCE_NUMBER:
     762            0 :         if (data_size != sizeof(uint64_t)) {
     763            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     764              :         }
     765            0 :         context->max_spdm_session_sequence_number = *(const uint64_t *)data;
     766            0 :         if (context->max_spdm_session_sequence_number == 0) {
     767            0 :             context->max_spdm_session_sequence_number = LIBSPDM_MAX_SPDM_SESSION_SEQUENCE_NUMBER;
     768              :         }
     769            0 :         break;
     770            0 :     case LIBSPDM_DATA_SPDM_VERSION_10_11_VERIFY_SIGNATURE_ENDIAN:
     771            0 :         if (data_size != sizeof(uint8_t)) {
     772            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     773              :         }
     774            0 :         if (*(const uint8_t*)data != LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY &&
     775            0 :             *(const uint8_t*)data != LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY &&
     776            0 :             *(const uint8_t*)data != LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE) {
     777            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     778              :         }
     779            0 :         context->spdm_10_11_verify_signature_endian = *(const uint8_t*)data;
     780            0 :         break;
     781            0 :     case LIBSPDM_DATA_SEQUENCE_NUMBER_ENDIAN:
     782            0 :         if (data_size != sizeof(uint8_t)) {
     783            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     784              :         }
     785            0 :         context->sequence_number_endian = *(const uint8_t *)data;
     786            0 :         break;
     787            0 :     case LIBSPDM_DATA_MULTI_KEY_CONN_REQ:
     788            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     789            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     790              :         }
     791            0 :         if (data_size != sizeof(bool)) {
     792            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     793              :         }
     794            0 :         context->connection_info.multi_key_conn_req = *(const bool *)data;
     795            0 :         break;
     796            0 :     case LIBSPDM_DATA_MULTI_KEY_CONN_RSP:
     797            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     798            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     799              :         }
     800            0 :         if (data_size != sizeof(bool)) {
     801            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     802              :         }
     803            0 :         context->connection_info.multi_key_conn_rsp = *(const bool *)data;
     804            0 :         break;
     805            0 :     case LIBSPDM_DATA_TOTAL_KEY_PAIRS:
     806            0 :         if (data_size != sizeof(uint8_t)) {
     807            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     808              :         }
     809            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     810            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     811              :         }
     812            0 :         context->local_context.total_key_pairs = *(const uint8_t *)data;
     813            0 :         break;
     814            0 :     default:
     815            0 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     816              :         break;
     817              :     }
     818              : 
     819           16 :     return LIBSPDM_STATUS_SUCCESS;
     820              : }
     821              : 
     822              : /**
     823              :  * Get an SPDM context data.
     824              :  *
     825              :  * @param  spdm_context                  A pointer to the SPDM context.
     826              :  * @param  data_type                     Type of the SPDM context data.
     827              :  * @param  parameter                    Type specific parameter of the SPDM context data.
     828              :  * @param  data                         A pointer to the SPDM context data.
     829              :  * @param  data_size                     size in bytes of the SPDM context data.
     830              :  *                                     On input, it means the size in bytes of data buffer.
     831              :  *                                     On output, it means the size in bytes of copied data buffer if RETURN_SUCCESS,
     832              :  *                                     and means the size in bytes of desired data buffer if RETURN_BUFFER_TOO_SMALL.
     833              :  *
     834              :  * @retval RETURN_SUCCESS               The SPDM context data is set successfully.
     835              :  * @retval RETURN_INVALID_PARAMETER     The data_size is NULL or the data is NULL and *data_size is not zero.
     836              :  * @retval RETURN_UNSUPPORTED           The data_type is unsupported.
     837              :  * @retval RETURN_NOT_FOUND             The data_type cannot be found.
     838              :  * @retval RETURN_NOT_READY             The data is not ready to return.
     839              :  * @retval RETURN_BUFFER_TOO_SMALL      The buffer is too small to hold the data.
     840              :  **/
     841           42 : libspdm_return_t libspdm_get_data(void *spdm_context, libspdm_data_type_t data_type,
     842              :                                   const libspdm_data_parameter_t *parameter,
     843              :                                   void *data, size_t *data_size)
     844              : {
     845              :     libspdm_context_t *context;
     846           42 :     libspdm_secured_message_context_t *secured_context = NULL;
     847              :     size_t target_data_size;
     848              :     void *target_data;
     849              :     uint32_t session_id;
     850              :     libspdm_session_info_t *session_info;
     851              :     size_t digest_size;
     852              :     size_t digest_count;
     853              :     uint8_t slot_id;
     854              :     size_t index;
     855              : 
     856           42 :     if (spdm_context == NULL || data == NULL || data_size == NULL ||
     857              :         data_type >= LIBSPDM_DATA_MAX) {
     858            0 :         return LIBSPDM_STATUS_INVALID_PARAMETER;
     859              :     }
     860              : 
     861           42 :     context = spdm_context;
     862              : 
     863           42 :     if (data_type == LIBSPDM_DATA_SESSION_END_SESSION_ATTRIBUTES) {
     864              :         /* end_session_attributes is present in both a session context as well as an
     865              :          * spdm context. */
     866            0 :         session_id = libspdm_read_uint32(parameter->additional_data);
     867            0 :         session_info = libspdm_get_session_info_via_session_id(context, session_id);
     868           42 :     } else if (need_session_info_for_data(data_type)) {
     869            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_SESSION) {
     870            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     871              :         }
     872            0 :         session_id = libspdm_read_uint32(parameter->additional_data);
     873            0 :         session_info = libspdm_get_session_info_via_session_id(context, session_id);
     874            0 :         if (session_info == NULL) {
     875            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     876              :         }
     877            0 :         secured_context = session_info->secured_message_context;
     878              :     } else {
     879           42 :         session_info = NULL;
     880              :     }
     881              : 
     882           42 :     switch (data_type) {
     883            0 :     case LIBSPDM_DATA_SPDM_VERSION:
     884            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     885            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     886              :         }
     887            0 :         target_data_size = sizeof(spdm_version_number_t);
     888            0 :         target_data = &(context->connection_info.version);
     889            0 :         break;
     890            0 :     case LIBSPDM_DATA_SECURED_MESSAGE_VERSION:
     891            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     892            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     893              :         }
     894            0 :         target_data_size = sizeof(spdm_version_number_t);
     895            0 :         target_data = &(context->connection_info.secured_message_version);
     896            0 :         break;
     897            0 :     case LIBSPDM_DATA_CAPABILITY_FLAGS:
     898            0 :         target_data_size = sizeof(uint32_t);
     899            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     900            0 :             target_data = &context->connection_info.capability.flags;
     901            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     902            0 :             target_data = &context->local_context.capability.flags;
     903              :         } else {
     904            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     905              :         }
     906            0 :         break;
     907            0 :     case LIBSPDM_DATA_CAPABILITY_CT_EXPONENT:
     908            0 :         target_data_size = sizeof(uint8_t);
     909            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     910            0 :             target_data = &context->connection_info.capability.ct_exponent;
     911            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     912            0 :             target_data = &context->local_context.capability.ct_exponent;
     913              :         } else {
     914            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     915              :         }
     916            0 :         break;
     917            0 :     case LIBSPDM_DATA_CAPABILITY_DATA_TRANSFER_SIZE:
     918            0 :         target_data_size = sizeof(uint32_t);
     919            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     920            0 :             target_data = &context->connection_info.capability.data_transfer_size;
     921            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     922            0 :             target_data = &context->local_context.capability.data_transfer_size;
     923              :         } else {
     924            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     925              :         }
     926            0 :         break;
     927            0 :     case LIBSPDM_DATA_CAPABILITY_MAX_SPDM_MSG_SIZE:
     928            0 :         target_data_size = sizeof(uint32_t);
     929            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     930            0 :             target_data = &context->connection_info.capability.max_spdm_msg_size;
     931            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     932            0 :             target_data = &context->local_context.capability.max_spdm_msg_size;
     933              :         } else {
     934            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     935              :         }
     936            0 :         break;
     937            0 :     case LIBSPDM_DATA_CAPABILITY_SENDER_DATA_TRANSFER_SIZE:
     938            0 :         target_data_size = sizeof(uint32_t);
     939            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     940            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     941            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     942            0 :             target_data = &context->local_context.capability.sender_data_transfer_size;
     943              :         } else {
     944            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     945              :         }
     946            0 :         break;
     947            0 :     case LIBSPDM_DATA_MEASUREMENT_SPEC:
     948            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     949            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     950              :         }
     951            0 :         target_data_size = sizeof(uint8_t);
     952            0 :         target_data = &context->connection_info.algorithm.measurement_spec;
     953            0 :         break;
     954            0 :     case LIBSPDM_DATA_MEASUREMENT_HASH_ALGO:
     955            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     956            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     957              :         }
     958            0 :         target_data_size = sizeof(uint32_t);
     959            0 :         target_data = &context->connection_info.algorithm.measurement_hash_algo;
     960            0 :         break;
     961            0 :     case LIBSPDM_DATA_BASE_ASYM_ALGO:
     962            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     963            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     964              :         }
     965            0 :         target_data_size = sizeof(uint32_t);
     966            0 :         target_data = &context->connection_info.algorithm.base_asym_algo;
     967            0 :         break;
     968            0 :     case LIBSPDM_DATA_BASE_HASH_ALGO:
     969            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     970            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     971              :         }
     972            0 :         target_data_size = sizeof(uint32_t);
     973            0 :         target_data = &context->connection_info.algorithm.base_hash_algo;
     974            0 :         break;
     975            0 :     case LIBSPDM_DATA_DHE_NAME_GROUP:
     976            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     977            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     978              :         }
     979            0 :         target_data_size = sizeof(uint16_t);
     980            0 :         target_data = &context->connection_info.algorithm.dhe_named_group;
     981            0 :         break;
     982            0 :     case LIBSPDM_DATA_AEAD_CIPHER_SUITE:
     983            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     984            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     985              :         }
     986            0 :         target_data_size = sizeof(uint16_t);
     987            0 :         target_data = &context->connection_info.algorithm.aead_cipher_suite;
     988            0 :         break;
     989            0 :     case LIBSPDM_DATA_REQ_BASE_ASYM_ALG:
     990            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     991            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     992              :         }
     993            0 :         target_data_size = sizeof(uint16_t);
     994            0 :         target_data = &context->connection_info.algorithm.req_base_asym_alg;
     995            0 :         break;
     996            0 :     case LIBSPDM_DATA_KEY_SCHEDULE:
     997            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     998            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     999              :         }
    1000            0 :         target_data_size = sizeof(uint16_t);
    1001            0 :         target_data = &context->connection_info.algorithm.key_schedule;
    1002            0 :         break;
    1003            0 :     case LIBSPDM_DATA_OTHER_PARAMS_SUPPORT:
    1004            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1005            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1006              :         }
    1007            0 :         target_data_size = sizeof(uint8_t);
    1008            0 :         target_data = &context->connection_info.algorithm.other_params_support;
    1009            0 :         break;
    1010            0 :     case LIBSPDM_DATA_MEL_SPEC:
    1011            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1012            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1013              :         }
    1014            0 :         target_data_size = sizeof(uint8_t);
    1015            0 :         target_data = &context->connection_info.algorithm.mel_spec;
    1016            0 :         break;
    1017            0 :     case LIBSPDM_DATA_CONNECTION_STATE:
    1018            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1019            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1020              :         }
    1021            0 :         target_data_size = sizeof(libspdm_connection_state_t);
    1022            0 :         target_data = &context->connection_info.connection_state;
    1023            0 :         break;
    1024            0 :     case LIBSPDM_DATA_RESPONSE_STATE:
    1025            0 :         target_data_size = sizeof(libspdm_response_state_t);
    1026            0 :         target_data = &context->response_state;
    1027            0 :         break;
    1028            5 :     case LIBSPDM_DATA_PEER_PROVISIONED_SLOT_MASK:
    1029            5 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1030            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1031              :         }
    1032            5 :         target_data_size = sizeof(uint8_t);
    1033            5 :         target_data = &context->connection_info.peer_provisioned_slot_mask;
    1034            5 :         break;
    1035            0 :     case LIBSPDM_DATA_PEER_SUPPORTED_SLOT_MASK:
    1036            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1037            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1038              :         }
    1039            0 :         target_data_size = sizeof(uint8_t);
    1040            0 :         target_data = &context->connection_info.peer_supported_slot_mask;
    1041            0 :         break;
    1042            5 :     case LIBSPDM_DATA_PEER_TOTAL_DIGEST_BUFFER:
    1043            5 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1044            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1045              :         }
    1046            5 :         digest_count = 0;
    1047           45 :         for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
    1048           40 :             if (context->connection_info.peer_provisioned_slot_mask & (1 << index)) {
    1049           12 :                 digest_count++;
    1050              :             }
    1051              :         }
    1052            5 :         digest_size = libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo);
    1053            5 :         target_data_size = digest_size * digest_count;
    1054            5 :         target_data = context->connection_info.peer_total_digest_buffer;
    1055            5 :         break;
    1056            0 :     case LIBSPDM_DATA_PEER_KEY_PAIR_ID:
    1057            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1058            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1059              :         }
    1060            0 :         slot_id = parameter->additional_data[0];
    1061            0 :         if (slot_id >= SPDM_MAX_SLOT_COUNT) {
    1062            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1063              :         }
    1064            0 :         target_data_size = sizeof(spdm_key_pair_id_t);
    1065            0 :         target_data = &context->connection_info.peer_key_pair_id[slot_id];
    1066            0 :         break;
    1067            0 :     case LIBSPDM_DATA_PEER_CERT_INFO:
    1068            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1069            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1070              :         }
    1071            0 :         slot_id = parameter->additional_data[0];
    1072            0 :         if (slot_id >= SPDM_MAX_SLOT_COUNT) {
    1073            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1074              :         }
    1075            0 :         target_data_size = sizeof(spdm_certificate_info_t);
    1076            0 :         target_data = &context->connection_info.peer_cert_info[slot_id];
    1077            0 :         break;
    1078            0 :     case LIBSPDM_DATA_PEER_KEY_USAGE_BIT_MASK:
    1079            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1080            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1081              :         }
    1082            0 :         slot_id = parameter->additional_data[0];
    1083            0 :         if (slot_id >= SPDM_MAX_SLOT_COUNT) {
    1084            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1085              :         }
    1086            0 :         target_data_size = sizeof(spdm_key_usage_bit_mask_t);
    1087            0 :         target_data = &context->connection_info.peer_key_usage_bit_mask[slot_id];
    1088            0 :         break;
    1089            0 :     case LIBSPDM_DATA_SESSION_USE_PSK:
    1090            0 :         target_data_size = sizeof(bool);
    1091            0 :         target_data = &session_info->use_psk;
    1092            0 :         break;
    1093            0 :     case LIBSPDM_DATA_SESSION_MUT_AUTH_REQUESTED:
    1094            0 :         target_data_size = sizeof(uint8_t);
    1095            0 :         target_data = &session_info->mut_auth_requested;
    1096            0 :         break;
    1097            0 :     case LIBSPDM_DATA_SESSION_END_SESSION_ATTRIBUTES:
    1098            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1099            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1100              :         }
    1101            0 :         target_data_size = sizeof(uint8_t);
    1102            0 :         if (session_info == NULL) {
    1103            0 :             target_data = &context->connection_info.end_session_attributes;
    1104              :         } else {
    1105            0 :             target_data = &session_info->end_session_attributes;
    1106              :         }
    1107            0 :         break;
    1108            0 :     case LIBSPDM_DATA_SESSION_POLICY:
    1109            0 :         target_data_size = sizeof(uint8_t);
    1110            0 :         target_data = &session_info->session_policy;
    1111            0 :         break;
    1112            6 :     case LIBSPDM_DATA_APP_CONTEXT_DATA:
    1113            6 :         target_data_size = sizeof(void *);
    1114            6 :         target_data = &context->app_context_data_ptr;
    1115            6 :         break;
    1116            0 :     case LIBSPDM_DATA_HANDLE_ERROR_RETURN_POLICY:
    1117            0 :         target_data_size = sizeof(uint8_t);
    1118            0 :         target_data = &context->handle_error_return_policy;
    1119            0 :         break;
    1120            0 :     case LIBSPDM_DATA_MAX_DHE_SESSION_COUNT:
    1121            0 :         target_data_size = sizeof(uint32_t);
    1122            0 :         target_data = &context->max_dhe_session_count;
    1123            0 :         break;
    1124            0 :     case LIBSPDM_DATA_MAX_PSK_SESSION_COUNT:
    1125            0 :         target_data_size = sizeof(uint32_t);
    1126            0 :         target_data = &context->max_psk_session_count;
    1127            0 :         break;
    1128            0 :     case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_REQ_DIR:
    1129            0 :         target_data_size = sizeof(uint64_t);
    1130            0 :         target_data = &secured_context->application_secret.request_data_sequence_number;
    1131            0 :         break;
    1132            0 :     case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_RSP_DIR:
    1133            0 :         target_data_size = sizeof(uint64_t);
    1134            0 :         target_data = &secured_context->application_secret.response_data_sequence_number;
    1135            0 :         break;
    1136            0 :     case LIBSPDM_DATA_MAX_SPDM_SESSION_SEQUENCE_NUMBER:
    1137            0 :         target_data_size = sizeof(uint64_t);
    1138            0 :         target_data = &context->max_spdm_session_sequence_number;
    1139            0 :         break;
    1140            0 :     case LIBSPDM_DATA_VCA_CACHE:
    1141            0 :         target_data_size = context->transcript.message_a.buffer_size;
    1142            0 :         target_data = context->transcript.message_a.buffer;
    1143            0 :         break;
    1144            0 :     case LIBSPDM_DATA_REQUEST_AND_SIZE:
    1145            0 :         target_data_size = context->last_spdm_request_size;
    1146            0 :         target_data = context->last_spdm_request;
    1147            0 :         break;
    1148            0 :     case LIBSPDM_DATA_SPDM_VERSION_10_11_VERIFY_SIGNATURE_ENDIAN:
    1149            0 :         target_data_size = sizeof(uint8_t);
    1150            0 :         target_data = &context->spdm_10_11_verify_signature_endian;
    1151            0 :         break;
    1152            0 :     case LIBSPDM_DATA_SEQUENCE_NUMBER_ENDIAN:
    1153            0 :         target_data_size = sizeof(uint8_t);
    1154            0 :         target_data = &context->sequence_number_endian;
    1155            0 :         break;
    1156            0 :     case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_ENDIAN:
    1157            0 :         target_data_size = sizeof(uint8_t);
    1158            0 :         target_data = &secured_context->sequence_number_endian;
    1159            0 :         break;
    1160            0 :     case LIBSPDM_DATA_MULTI_KEY_CONN_REQ:
    1161            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1162            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1163              :         }
    1164            0 :         target_data_size = sizeof(bool);
    1165            0 :         target_data = &context->connection_info.multi_key_conn_req;
    1166            0 :         break;
    1167            0 :     case LIBSPDM_DATA_MULTI_KEY_CONN_RSP:
    1168            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1169            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1170              :         }
    1171            0 :         target_data_size = sizeof(bool);
    1172            0 :         target_data = &context->connection_info.multi_key_conn_rsp;
    1173            0 :         break;
    1174           26 :     case LIBSPDM_DATA_TOTAL_KEY_PAIRS:
    1175           26 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
    1176            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1177              :         }
    1178           26 :         target_data_size = sizeof(uint8_t);
    1179           26 :         target_data = &context->local_context.total_key_pairs;
    1180           26 :         break;
    1181            0 :     default:
    1182            0 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
    1183              :         break;
    1184              :     }
    1185              : 
    1186           42 :     if (*data_size < target_data_size) {
    1187            1 :         *data_size = target_data_size;
    1188            1 :         return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
    1189              :     }
    1190           41 :     libspdm_copy_mem(data, *data_size, target_data, target_data_size);
    1191           41 :     *data_size = target_data_size;
    1192              : 
    1193           41 :     return LIBSPDM_STATUS_SUCCESS;
    1194              : }
    1195              : 
    1196              : #if LIBSPDM_CHECK_SPDM_CONTEXT
    1197            3 : bool libspdm_check_context (void *spdm_context)
    1198              : {
    1199              :     libspdm_context_t *context;
    1200              :     size_t index;
    1201              : 
    1202            3 :     context = spdm_context;
    1203              : 
    1204            3 :     if (context->local_context.capability.data_transfer_size <
    1205              :         SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12) {
    1206            1 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
    1207              :                        "data_transfer_size must be greater than or equal "
    1208              :                        "to SPDM_MIN_DATA_TRANSFER_SIZE (%d).\n",
    1209              :                        SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12));
    1210            1 :         return false;
    1211              :     }
    1212              : 
    1213            2 :     if (context->local_context.capability.max_spdm_msg_size <
    1214            2 :         context->local_context.capability.data_transfer_size) {
    1215            1 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
    1216              :                        "max_spdm_msg_size (%d) must be greater than or "
    1217              :                        "equal to data_transfer_size (%d).\n",
    1218              :                        context->local_context.capability.max_spdm_msg_size,
    1219              :                        context->local_context.capability.data_transfer_size));
    1220            1 :         return false;
    1221              :     }
    1222              : 
    1223            1 :     if (context->local_context.capability.sender_data_transfer_size <
    1224              :         SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12) {
    1225            0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
    1226              :                        "sender_data_transfer_size must be greater than or equal "
    1227              :                        "to %d.\n", SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12));
    1228            0 :         return false;
    1229              :     }
    1230              : 
    1231            1 :     if (context->local_context.capability.max_spdm_msg_size <
    1232            1 :         context->local_context.capability.sender_data_transfer_size) {
    1233            0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
    1234              :                        "max_spdm_msg_size (%d) must be greater than or "
    1235              :                        "equal to sender_data_transfer_size (%d).\n",
    1236              :                        context->local_context.capability.max_spdm_msg_size,
    1237              :                        context->local_context.capability.sender_data_transfer_size));
    1238            0 :         return false;
    1239              :     }
    1240              : 
    1241            1 :     if (((context->local_context.capability.flags &
    1242            0 :           SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP) != 0) &&
    1243            0 :         (context->local_context.capability.max_spdm_msg_size != 0)) {
    1244            0 :         for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
    1245            0 :             if ((context->local_context.local_cert_chain_provision_size[index] != 0) &&
    1246            0 :                 (context->local_context.local_cert_chain_provision_size[index] +
    1247              :                  sizeof(spdm_certificate_response_t) >
    1248            0 :                  context->local_context.capability.max_spdm_msg_size)) {
    1249            0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
    1250              :                                "max_spdm_msg_size (%d) must be greater than or "
    1251              :                                "equal to local_cert_chain_provision_size[%zu] (%zu).\n",
    1252              :                                context->local_context.capability.max_spdm_msg_size, index,
    1253              :                                context->local_context.local_cert_chain_provision_size[index]));
    1254            0 :                 return false;
    1255              :             }
    1256              :         }
    1257              :     }
    1258              : 
    1259            1 :     return true;
    1260              : }
    1261              : #endif /* LIBSPDM_CHECK_CONTEXT */
    1262              : 
    1263              : /**
    1264              :  * Reset message A cache in SPDM context.
    1265              :  *
    1266              :  * @param  spdm_context                  A pointer to the SPDM context.
    1267              :  **/
    1268          666 : void libspdm_reset_message_a(libspdm_context_t *spdm_context)
    1269              : {
    1270          666 :     libspdm_reset_managed_buffer(&spdm_context->transcript.message_a);
    1271          666 : }
    1272              : 
    1273              : /**
    1274              :  * Reset message D cache in SPDM context.
    1275              :  *
    1276              :  * @param  spdm_context                  A pointer to the SPDM context.
    1277              :  **/
    1278           51 : void libspdm_reset_message_d(libspdm_context_t *spdm_context)
    1279              : {
    1280           51 :     libspdm_reset_managed_buffer(&spdm_context->transcript.message_d);
    1281           51 : }
    1282              : 
    1283              : /**
    1284              :  * Reset message B cache in SPDM context.
    1285              :  *
    1286              :  * @param  spdm_context                  A pointer to the SPDM context.
    1287              :  **/
    1288         1005 : void libspdm_reset_message_b(libspdm_context_t *spdm_context)
    1289              : {
    1290              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1291              :     libspdm_reset_managed_buffer(&spdm_context->transcript.message_b);
    1292              : #else
    1293         1005 :     if (spdm_context->transcript.digest_context_m1m2 != NULL) {
    1294          182 :         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1295              :                            spdm_context->transcript.digest_context_m1m2);
    1296          182 :         spdm_context->transcript.digest_context_m1m2 = NULL;
    1297              :     }
    1298              : #endif
    1299         1005 : }
    1300              : 
    1301              : /**
    1302              :  * Reset message C cache in SPDM context.
    1303              :  *
    1304              :  * @param  spdm_context                  A pointer to the SPDM context.
    1305              :  **/
    1306          580 : void libspdm_reset_message_c(libspdm_context_t *spdm_context)
    1307              : {
    1308              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1309              :     libspdm_reset_managed_buffer(&spdm_context->transcript.message_c);
    1310              : #else
    1311          580 :     if (spdm_context->transcript.digest_context_m1m2 != NULL) {
    1312            0 :         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1313              :                            spdm_context->transcript.digest_context_m1m2);
    1314            0 :         spdm_context->transcript.digest_context_m1m2 = NULL;
    1315              :     }
    1316              : #endif
    1317          580 : }
    1318              : 
    1319              : /**
    1320              :  * Reset message MutB cache in SPDM context.
    1321              :  *
    1322              :  * @param  spdm_context                  A pointer to the SPDM context.
    1323              :  **/
    1324          450 : void libspdm_reset_message_mut_b(libspdm_context_t *spdm_context)
    1325              : {
    1326              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1327              :     libspdm_reset_managed_buffer(&spdm_context->transcript.message_mut_b);
    1328              : #else
    1329          450 :     if (spdm_context->transcript.digest_context_mut_m1m2 != NULL) {
    1330           18 :         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1331              :                            spdm_context->transcript.digest_context_mut_m1m2);
    1332           18 :         spdm_context->transcript.digest_context_mut_m1m2 = NULL;
    1333              :     }
    1334              : #endif
    1335          450 : }
    1336              : 
    1337              : /**
    1338              :  * Reset message MutC cache in SPDM context.
    1339              :  *
    1340              :  * @param  spdm_context                  A pointer to the SPDM context.
    1341              :  **/
    1342          449 : void libspdm_reset_message_mut_c(libspdm_context_t *spdm_context)
    1343              : {
    1344              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1345              :     libspdm_reset_managed_buffer(&spdm_context->transcript.message_mut_c);
    1346              : #else
    1347          449 :     if (spdm_context->transcript.digest_context_mut_m1m2 != NULL) {
    1348            0 :         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1349              :                            spdm_context->transcript.digest_context_mut_m1m2);
    1350            0 :         spdm_context->transcript.digest_context_mut_m1m2 = NULL;
    1351              :     }
    1352              : #endif
    1353          449 : }
    1354              : 
    1355              : /**
    1356              :  * Reset message M cache in SPDM context.
    1357              :  * If session_info is NULL, this function will use M cache of SPDM context,
    1358              :  * else will use M cache of SPDM session context.
    1359              :  *
    1360              :  * @param  spdm_context                  A pointer to the SPDM context.
    1361              :  * @param  session_info                  A pointer to the SPDM session context.
    1362              :  **/
    1363         4130 : void libspdm_reset_message_m(libspdm_context_t *spdm_context, void *session_info)
    1364              : {
    1365              :     libspdm_session_info_t *spdm_session_info;
    1366              : 
    1367         4130 :     spdm_session_info = session_info;
    1368              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1369              :     if (spdm_session_info == NULL) {
    1370              :         libspdm_reset_managed_buffer(&spdm_context->transcript.message_m);
    1371              :     } else {
    1372              :         libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_m);
    1373              :     }
    1374              : #else
    1375         4130 :     if (spdm_session_info == NULL) {
    1376         3861 :         if (spdm_context->transcript.digest_context_l1l2 != NULL) {
    1377           62 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1378              :                                spdm_context->transcript.digest_context_l1l2);
    1379           62 :             spdm_context->transcript.digest_context_l1l2 = NULL;
    1380              :         }
    1381              :     } else {
    1382          269 :         if (spdm_session_info->session_transcript.digest_context_l1l2 != NULL) {
    1383            2 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1384              :                                spdm_session_info->session_transcript.digest_context_l1l2);
    1385            2 :             spdm_session_info->session_transcript.digest_context_l1l2 = NULL;
    1386              :         }
    1387              :     }
    1388              : #endif
    1389         4130 : }
    1390              : 
    1391              : /**
    1392              :  * Reset message K cache in SPDM context.
    1393              :  *
    1394              :  * @param  spdm_context                  A pointer to the SPDM context.
    1395              :  * @param  spdm_session_info              A pointer to the SPDM session context.
    1396              :  **/
    1397            0 : void libspdm_reset_message_k(libspdm_context_t *spdm_context, void *session_info)
    1398              : {
    1399              :     libspdm_session_info_t *spdm_session_info;
    1400              : 
    1401            0 :     spdm_session_info = session_info;
    1402              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1403              :     libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_k);
    1404              : #else
    1405              :     {
    1406            0 :         if (spdm_session_info->session_transcript.digest_context_th != NULL) {
    1407            0 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1408              :                                spdm_session_info->session_transcript.digest_context_th);
    1409            0 :             spdm_session_info->session_transcript.digest_context_th = NULL;
    1410              :         }
    1411            0 :         if (spdm_session_info->session_transcript.digest_context_th_backup != NULL) {
    1412            0 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1413              :                                spdm_session_info->session_transcript.digest_context_th_backup);
    1414            0 :             spdm_session_info->session_transcript.digest_context_th_backup = NULL;
    1415              :         }
    1416              :     }
    1417              : #endif
    1418            0 : }
    1419              : 
    1420              : /**
    1421              :  * Reset message EncapD cache in SPDM context.
    1422              :  *
    1423              :  * @param  spdm_context                  A pointer to the SPDM context.
    1424              :  * @param  spdm_session_info              A pointer to the SPDM session context.
    1425              :  **/
    1426            6 : void libspdm_reset_message_encap_d(libspdm_context_t *spdm_context, void *session_info)
    1427              : {
    1428              :     libspdm_session_info_t *spdm_session_info;
    1429              : 
    1430            6 :     spdm_session_info = session_info;
    1431            6 :     libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_encap_d);
    1432            6 : }
    1433              : 
    1434              : /**
    1435              :  * Reset message F cache in SPDM context.
    1436              :  *
    1437              :  * @param  spdm_context                  A pointer to the SPDM context.
    1438              :  * @param  spdm_session_info              A pointer to the SPDM session context.
    1439              :  **/
    1440           21 : void libspdm_reset_message_f(libspdm_context_t *spdm_context, void *session_info)
    1441              : {
    1442              :     libspdm_session_info_t *spdm_session_info;
    1443              : 
    1444           21 :     spdm_session_info = session_info;
    1445              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1446              :     libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_f);
    1447              : #else
    1448              :     {
    1449           21 :         if (spdm_session_info->session_transcript.digest_context_th != NULL) {
    1450           21 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1451              :                                spdm_session_info->session_transcript.digest_context_th);
    1452           21 :             spdm_session_info->session_transcript.digest_context_th =
    1453           21 :                 spdm_session_info->session_transcript.digest_context_th_backup;
    1454           21 :             spdm_session_info->session_transcript.digest_context_th_backup = NULL;
    1455              :         }
    1456           21 :         spdm_session_info->session_transcript.message_f_initialized = false;
    1457              :     }
    1458              : #endif
    1459           21 : }
    1460              : 
    1461              : /**
    1462              :  * Reset message E cache in SPDM context.
    1463              :  * If session_info is NULL, this function will use E cache of SPDM context,
    1464              :  * else will use E cache of SPDM session context.
    1465              :  *
    1466              :  * @param  spdm_context                  A pointer to the SPDM context.
    1467              :  * @param  spdm_session_info              A pointer to the SPDM session context.
    1468              :  **/
    1469          143 : void libspdm_reset_message_e(libspdm_context_t *spdm_context, void *session_info)
    1470              : {
    1471              :     libspdm_session_info_t *spdm_session_info;
    1472              : 
    1473          143 :     spdm_session_info = session_info;
    1474              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1475              :     if (spdm_session_info == NULL) {
    1476              :         libspdm_reset_managed_buffer(&spdm_context->transcript.message_e);
    1477              :     } else {
    1478              :         libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_e);
    1479              :     }
    1480              : #else
    1481          143 :     if (spdm_session_info == NULL) {
    1482          135 :         if (spdm_context->transcript.digest_context_il1il2 != NULL) {
    1483           14 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1484              :                                spdm_context->transcript.digest_context_il1il2);
    1485           14 :             spdm_context->transcript.digest_context_il1il2 = NULL;
    1486              :         }
    1487              :     } else {
    1488            8 :         if (spdm_session_info->session_transcript.digest_context_il1il2 != NULL) {
    1489            3 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1490              :                                spdm_session_info->session_transcript.digest_context_il1il2);
    1491            3 :             spdm_session_info->session_transcript.digest_context_il1il2 = NULL;
    1492              :         }
    1493              :     }
    1494              : #endif
    1495          143 : }
    1496              : 
    1497              : /**
    1498              :  * Reset message encap E cache in SPDM context.
    1499              :  * If session_info is NULL, this function will use encap E cache of SPDM context,
    1500              :  * else will use encap E cache of SPDM session context.
    1501              :  *
    1502              :  * @param  spdm_context                  A pointer to the SPDM context.
    1503              :  * @param  spdm_session_info              A pointer to the SPDM session context.
    1504              :  **/
    1505          102 : void libspdm_reset_message_encap_e(libspdm_context_t *spdm_context, void *session_info)
    1506              : {
    1507              :     libspdm_session_info_t *spdm_session_info;
    1508              : 
    1509          102 :     spdm_session_info = session_info;
    1510              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1511              :     if (spdm_session_info == NULL) {
    1512              :         libspdm_reset_managed_buffer(&spdm_context->transcript.message_encap_e);
    1513              :     } else {
    1514              :         libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_encap_e);
    1515              :     }
    1516              : #else
    1517          102 :     if (spdm_session_info == NULL) {
    1518           95 :         if (spdm_context->transcript.digest_context_encap_il1il2 != NULL) {
    1519           12 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1520              :                                spdm_context->transcript.digest_context_encap_il1il2);
    1521           12 :             spdm_context->transcript.digest_context_encap_il1il2 = NULL;
    1522              :         }
    1523              :     } else {
    1524            7 :         if (spdm_session_info->session_transcript.digest_context_encap_il1il2 != NULL) {
    1525            2 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1526              :                                spdm_session_info->session_transcript.digest_context_encap_il1il2);
    1527            2 :             spdm_session_info->session_transcript.digest_context_encap_il1il2 = NULL;
    1528              :         }
    1529              :     }
    1530              : #endif
    1531          102 : }
    1532              : 
    1533              : /**
    1534              :  * Reset message buffer in SPDM context according to request code.
    1535              :  *
    1536              :  * @param  spdm_context                   A pointer to the SPDM context.
    1537              :  * @param  spdm_session_info             A pointer to the SPDM session context.
    1538              :  * @param  spdm_request                   The SPDM request code.
    1539              :  */
    1540         4266 : void libspdm_reset_message_buffer_via_request_code(void *context, void *session_info,
    1541              :                                                    uint8_t request_code)
    1542              : {
    1543              :     libspdm_context_t *spdm_context;
    1544              : 
    1545         4266 :     spdm_context = context;
    1546              :     /**
    1547              :      * Any request other than SPDM_GET_MEASUREMENTS resets L1/L2
    1548              :      */
    1549         4266 :     if (request_code != SPDM_GET_MEASUREMENTS) {
    1550         3841 :         libspdm_reset_message_m(spdm_context, session_info);
    1551              :     }
    1552              :     /**
    1553              :      * If the Requester issued GET_MEASUREMENTS or KEY_EXCHANGE or FINISH or PSK_EXCHANGE
    1554              :      * or PSK_FINISH or KEY_UPDATE or HEARTBEAT or GET_ENCAPSULATED_REQUEST or DELIVER_ENCAPSULATED_RESPONSE
    1555              :      * or END_SESSION request(s) or SPDM_GET_MEASUREMENT_EXTENSION_LOG and skipped CHALLENGE completion, M1 and M2 are reset to null.
    1556              :      */
    1557         4266 :     switch (request_code)
    1558              :     {
    1559          869 :     case SPDM_KEY_EXCHANGE:
    1560              :     case SPDM_GET_MEASUREMENTS:
    1561              :     case SPDM_FINISH:
    1562              :     case SPDM_PSK_EXCHANGE:
    1563              :     case SPDM_PSK_FINISH:
    1564              :     case SPDM_KEY_UPDATE:
    1565              :     case SPDM_HEARTBEAT:
    1566              :     case SPDM_GET_ENCAPSULATED_REQUEST:
    1567              :     case SPDM_END_SESSION:
    1568              :     case SPDM_GET_MEASUREMENT_EXTENSION_LOG:
    1569          869 :         if (spdm_context->connection_info.connection_state <
    1570              :             LIBSPDM_CONNECTION_STATE_AUTHENTICATED) {
    1571          427 :             libspdm_reset_message_b(spdm_context);
    1572          427 :             libspdm_reset_message_c(spdm_context);
    1573          427 :             libspdm_reset_message_mut_b(spdm_context);
    1574          427 :             libspdm_reset_message_mut_c(spdm_context);
    1575              :         }
    1576          869 :         break;
    1577            5 :     case SPDM_DELIVER_ENCAPSULATED_RESPONSE:
    1578            5 :         if (spdm_context->connection_info.connection_state <
    1579              :             LIBSPDM_CONNECTION_STATE_AUTHENTICATED) {
    1580            5 :             libspdm_reset_message_b(spdm_context);
    1581            5 :             libspdm_reset_message_c(spdm_context);
    1582              :         }
    1583            5 :         break;
    1584           58 :     case SPDM_GET_DIGESTS:
    1585           58 :         libspdm_reset_message_b(spdm_context);
    1586           58 :         break;
    1587           56 :     case SPDM_GET_ENDPOINT_INFO:
    1588           56 :         libspdm_reset_message_e(spdm_context, session_info);
    1589           56 :         libspdm_reset_message_encap_e(spdm_context, session_info);
    1590           56 :         break;
    1591         3278 :     default:
    1592         3278 :         break;
    1593              :     }
    1594         4266 : }
    1595              : /**
    1596              :  * Append message A cache in SPDM context.
    1597              :  *
    1598              :  * @param  spdm_context                  A pointer to the SPDM context.
    1599              :  * @param  message                      message buffer.
    1600              :  * @param  message_size                  size in bytes of message buffer.
    1601              :  *
    1602              :  * @return RETURN_SUCCESS          message is appended.
    1603              :  * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
    1604              :  **/
    1605          169 : libspdm_return_t libspdm_append_message_a(libspdm_context_t *spdm_context, const void *message,
    1606              :                                           size_t message_size)
    1607              : {
    1608          169 :     return libspdm_append_managed_buffer(&spdm_context->transcript.message_a,
    1609              :                                          message, message_size);
    1610              : }
    1611              : 
    1612              : /**
    1613              :  * Append message D cache in SPDM context.
    1614              :  *
    1615              :  * @param  spdm_context  A pointer to the SPDM context.
    1616              :  * @param  message       Message buffer.
    1617              :  * @param  message_size  Size in bytes of message buffer.
    1618              :  *
    1619              :  * @return RETURN_SUCCESS          message is appended.
    1620              :  * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
    1621              :  **/
    1622            7 : libspdm_return_t libspdm_append_message_d(libspdm_context_t *spdm_context, const void *message,
    1623              :                                           size_t message_size)
    1624              : {
    1625              :     /* Only the first message D after VCA in connection counts  */
    1626            7 :     if (libspdm_get_managed_buffer_size(&spdm_context->transcript.message_d) != 0) {
    1627            1 :         return LIBSPDM_STATUS_SUCCESS;
    1628              :     }
    1629            6 :     return libspdm_append_managed_buffer(&spdm_context->transcript.message_d,
    1630              :                                          message, message_size);
    1631              : }
    1632              : 
    1633              : /**
    1634              :  * Append message B cache in SPDM context.
    1635              :  *
    1636              :  * @param  spdm_context                  A pointer to the SPDM context.
    1637              :  * @param  message                      message buffer.
    1638              :  * @param  message_size                  size in bytes of message buffer.
    1639              :  *
    1640              :  * @return RETURN_SUCCESS          message is appended.
    1641              :  * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
    1642              :  **/
    1643         5932 : libspdm_return_t libspdm_append_message_b(libspdm_context_t *spdm_context, const void *message,
    1644              :                                           size_t message_size)
    1645              : {
    1646              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1647              :     return libspdm_append_managed_buffer(&spdm_context->transcript.message_b,
    1648              :                                          message, message_size);
    1649              : #else
    1650              :     {
    1651              :         bool result;
    1652              : 
    1653         5932 :         if (spdm_context->transcript.digest_context_m1m2 == NULL) {
    1654          162 :             spdm_context->transcript.digest_context_m1m2 = libspdm_hash_new (
    1655              :                 spdm_context->connection_info.algorithm.base_hash_algo);
    1656          162 :             if (spdm_context->transcript.digest_context_m1m2 == NULL) {
    1657            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1658              :             }
    1659          162 :             result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    1660              :                                         spdm_context->transcript.digest_context_m1m2);
    1661          162 :             if (!result) {
    1662            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1663              :                                    spdm_context->transcript.digest_context_m1m2);
    1664            0 :                 spdm_context->transcript.digest_context_m1m2 = NULL;
    1665            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1666              :             }
    1667          162 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    1668              :                                           spdm_context->transcript.digest_context_m1m2,
    1669          162 :                                           libspdm_get_managed_buffer(&spdm_context->transcript.
    1670              :                                                                      message_a),
    1671          162 :                                           libspdm_get_managed_buffer_size(&spdm_context->transcript.
    1672              :                                                                           message_a));
    1673          162 :             if (!result) {
    1674            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1675              :                                    spdm_context->transcript.digest_context_m1m2);
    1676            0 :                 spdm_context->transcript.digest_context_m1m2 = NULL;
    1677            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1678              :             }
    1679              :         }
    1680              : 
    1681         5932 :         result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    1682              :                                       spdm_context->transcript.digest_context_m1m2, message,
    1683              :                                       message_size);
    1684         5932 :         if (!result) {
    1685            0 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1686              :                                spdm_context->transcript.digest_context_m1m2);
    1687            0 :             spdm_context->transcript.digest_context_m1m2 = NULL;
    1688            0 :             return LIBSPDM_STATUS_CRYPTO_ERROR;
    1689              :         }
    1690              : 
    1691         5932 :         return LIBSPDM_STATUS_SUCCESS;
    1692              :     }
    1693              : #endif
    1694              : }
    1695              : 
    1696              : /**
    1697              :  * Append message C cache in SPDM context.
    1698              :  *
    1699              :  * @param  spdm_context                  A pointer to the SPDM context.
    1700              :  * @param  message                      message buffer.
    1701              :  * @param  message_size                  size in bytes of message buffer.
    1702              :  *
    1703              :  * @return RETURN_SUCCESS          message is appended.
    1704              :  * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
    1705              :  **/
    1706           50 : libspdm_return_t libspdm_append_message_c(libspdm_context_t *spdm_context, const void *message,
    1707              :                                           size_t message_size)
    1708              : {
    1709              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1710              :     return libspdm_append_managed_buffer(&spdm_context->transcript.message_c,
    1711              :                                          message, message_size);
    1712              : #else
    1713              :     {
    1714              :         bool result;
    1715              : 
    1716           50 :         if (spdm_context->transcript.digest_context_m1m2 == NULL) {
    1717           24 :             spdm_context->transcript.digest_context_m1m2 = libspdm_hash_new (
    1718              :                 spdm_context->connection_info.algorithm.base_hash_algo);
    1719           24 :             if (spdm_context->transcript.digest_context_m1m2 == NULL) {
    1720            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1721              :             }
    1722           24 :             result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    1723              :                                         spdm_context->transcript.digest_context_m1m2);
    1724           24 :             if (!result) {
    1725            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1726              :                                    spdm_context->transcript.digest_context_m1m2);
    1727            0 :                 spdm_context->transcript.digest_context_m1m2 = NULL;
    1728            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1729              :             }
    1730           24 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    1731              :                                           spdm_context->transcript.digest_context_m1m2,
    1732           24 :                                           libspdm_get_managed_buffer(&spdm_context->transcript.
    1733              :                                                                      message_a),
    1734           24 :                                           libspdm_get_managed_buffer_size(&spdm_context->transcript.
    1735              :                                                                           message_a));
    1736           24 :             if (!result) {
    1737            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1738              :                                    spdm_context->transcript.digest_context_m1m2);
    1739            0 :                 spdm_context->transcript.digest_context_m1m2 = NULL;
    1740            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1741              :             }
    1742              :         }
    1743              : 
    1744           50 :         result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    1745              :                                       spdm_context->transcript.digest_context_m1m2, message,
    1746              :                                       message_size);
    1747           50 :         if (!result) {
    1748            0 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1749              :                                spdm_context->transcript.digest_context_m1m2);
    1750            0 :             spdm_context->transcript.digest_context_m1m2 = NULL;
    1751            0 :             return LIBSPDM_STATUS_CRYPTO_ERROR;
    1752              :         }
    1753              : 
    1754           50 :         return LIBSPDM_STATUS_SUCCESS;
    1755              :     }
    1756              : #endif
    1757              : }
    1758              : 
    1759              : /**
    1760              :  * Append message MutB cache in SPDM context.
    1761              :  *
    1762              :  * @param  spdm_context                  A pointer to the SPDM context.
    1763              :  * @param  message                      message buffer.
    1764              :  * @param  message_size                  size in bytes of message buffer.
    1765              :  *
    1766              :  * @return RETURN_SUCCESS          message is appended.
    1767              :  * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
    1768              :  **/
    1769         2831 : libspdm_return_t libspdm_append_message_mut_b(libspdm_context_t *spdm_context, const void *message,
    1770              :                                               size_t message_size)
    1771              : {
    1772              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1773              :     return libspdm_append_managed_buffer(&spdm_context->transcript.message_mut_b,
    1774              :                                          message, message_size);
    1775              : #else
    1776              :     {
    1777              :         bool result;
    1778              : 
    1779         2831 :         if (spdm_context->transcript.digest_context_mut_m1m2 == NULL) {
    1780           16 :             spdm_context->transcript.digest_context_mut_m1m2 = libspdm_hash_new (
    1781              :                 spdm_context->connection_info.algorithm.base_hash_algo);
    1782           16 :             if (spdm_context->transcript.digest_context_mut_m1m2 == NULL) {
    1783            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1784              :             }
    1785           16 :             result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    1786              :                                         spdm_context->transcript.digest_context_mut_m1m2);
    1787           16 :             if (!result) {
    1788            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1789              :                                    spdm_context->transcript.digest_context_mut_m1m2);
    1790            0 :                 spdm_context->transcript.digest_context_mut_m1m2 = NULL;
    1791            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1792              :             }
    1793           16 :             if ((spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >
    1794              :                 SPDM_MESSAGE_VERSION_11) {
    1795              : 
    1796              :                 /* Need append VCA since 1.2 script */
    1797            5 :                 result = libspdm_hash_update (
    1798              :                     spdm_context->connection_info.algorithm.base_hash_algo,
    1799              :                     spdm_context->transcript.digest_context_mut_m1m2,
    1800            5 :                     libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
    1801            5 :                     libspdm_get_managed_buffer_size(&spdm_context->transcript.
    1802              :                                                     message_a));
    1803            5 :                 if (!result) {
    1804            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1805              :                                        spdm_context->transcript.digest_context_mut_m1m2);
    1806            0 :                     spdm_context->transcript.digest_context_mut_m1m2 = NULL;
    1807            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    1808              :                 }
    1809              :             }
    1810              :         }
    1811              : 
    1812         2831 :         result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    1813              :                                       spdm_context->transcript.digest_context_mut_m1m2, message,
    1814              :                                       message_size);
    1815         2831 :         if (!result) {
    1816            0 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1817              :                                spdm_context->transcript.digest_context_mut_m1m2);
    1818            0 :             spdm_context->transcript.digest_context_mut_m1m2 = NULL;
    1819            0 :             return LIBSPDM_STATUS_CRYPTO_ERROR;
    1820              :         }
    1821              : 
    1822         2831 :         return LIBSPDM_STATUS_SUCCESS;
    1823              :     }
    1824              : #endif
    1825              : }
    1826              : 
    1827              : /**
    1828              :  * Append message MutC cache in SPDM context.
    1829              :  *
    1830              :  * @param  spdm_context                  A pointer to the SPDM context.
    1831              :  * @param  message                      message buffer.
    1832              :  * @param  message_size                  size in bytes of message buffer.
    1833              :  *
    1834              :  * @return RETURN_SUCCESS          message is appended.
    1835              :  * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
    1836              :  **/
    1837           10 : libspdm_return_t libspdm_append_message_mut_c(libspdm_context_t *spdm_context, const void *message,
    1838              :                                               size_t message_size)
    1839              : {
    1840              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1841              :     return libspdm_append_managed_buffer(&spdm_context->transcript.message_mut_c,
    1842              :                                          message, message_size);
    1843              : #else
    1844              :     {
    1845              :         bool result;
    1846              : 
    1847           10 :         if (spdm_context->transcript.digest_context_mut_m1m2 == NULL) {
    1848            7 :             spdm_context->transcript.digest_context_mut_m1m2 = libspdm_hash_new (
    1849              :                 spdm_context->connection_info.algorithm.base_hash_algo);
    1850            7 :             if (spdm_context->transcript.digest_context_mut_m1m2 == NULL) {
    1851            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1852              :             }
    1853            7 :             result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    1854              :                                         spdm_context->transcript.digest_context_mut_m1m2);
    1855            7 :             if (!result) {
    1856            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1857              :                                    spdm_context->transcript.digest_context_mut_m1m2);
    1858            0 :                 spdm_context->transcript.digest_context_mut_m1m2 = NULL;
    1859            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1860              :             }
    1861            7 :             if ((spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >
    1862              :                 SPDM_MESSAGE_VERSION_11) {
    1863              : 
    1864              :                 /* Need append VCA since 1.2 script */
    1865            2 :                 result = libspdm_hash_update (
    1866              :                     spdm_context->connection_info.algorithm.base_hash_algo,
    1867              :                     spdm_context->transcript.digest_context_mut_m1m2,
    1868            2 :                     libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
    1869            2 :                     libspdm_get_managed_buffer_size(&spdm_context->transcript.
    1870              :                                                     message_a));
    1871            2 :                 if (!result) {
    1872            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1873              :                                        spdm_context->transcript.digest_context_mut_m1m2);
    1874            0 :                     spdm_context->transcript.digest_context_mut_m1m2 = NULL;
    1875            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    1876              :                 }
    1877              :             }
    1878              :         }
    1879              : 
    1880           10 :         result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    1881              :                                       spdm_context->transcript.digest_context_mut_m1m2, message,
    1882              :                                       message_size);
    1883           10 :         if (!result) {
    1884            0 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1885              :                                spdm_context->transcript.digest_context_mut_m1m2);
    1886            0 :             spdm_context->transcript.digest_context_mut_m1m2 = NULL;
    1887            0 :             return LIBSPDM_STATUS_CRYPTO_ERROR;
    1888              :         }
    1889              : 
    1890           10 :         return LIBSPDM_STATUS_SUCCESS;
    1891              :     }
    1892              : #endif
    1893              : }
    1894              : 
    1895              : /**
    1896              :  * Append message M cache in SPDM context.
    1897              :  * If session_info is NULL, this function will use M cache of SPDM context,
    1898              :  * else will use M cache of SPDM session context.
    1899              :  *
    1900              :  * @param  spdm_context                  A pointer to the SPDM context.
    1901              :  * @param  session_info                  A pointer to the SPDM session context.
    1902              :  * @param  message                      message buffer.
    1903              :  * @param  message_size                  size in bytes of message buffer.
    1904              :  *
    1905              :  * @return RETURN_SUCCESS          message is appended.
    1906              :  * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
    1907              :  **/
    1908          722 : libspdm_return_t libspdm_append_message_m(libspdm_context_t *spdm_context, void *session_info,
    1909              :                                           const void *message, size_t message_size)
    1910              : {
    1911              :     libspdm_session_info_t *spdm_session_info;
    1912              : 
    1913          722 :     spdm_session_info = session_info;
    1914              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1915              :     if (spdm_session_info == NULL) {
    1916              :         return libspdm_append_managed_buffer(&spdm_context->transcript.message_m,
    1917              :                                              message, message_size);
    1918              :     } else {
    1919              :         return libspdm_append_managed_buffer(&spdm_session_info->session_transcript.message_m,
    1920              :                                              message, message_size);
    1921              :     }
    1922              : #else
    1923              :     {
    1924              :         bool result;
    1925              : 
    1926          722 :         if (spdm_session_info == NULL) {
    1927          718 :             if (spdm_context->transcript.digest_context_l1l2 == NULL) {
    1928           62 :                 spdm_context->transcript.digest_context_l1l2 = libspdm_hash_new (
    1929              :                     spdm_context->connection_info.algorithm.base_hash_algo);
    1930           62 :                 if (spdm_context->transcript.digest_context_l1l2 == NULL) {
    1931            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    1932              :                 }
    1933           62 :                 result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    1934              :                                             spdm_context->transcript.digest_context_l1l2);
    1935           62 :                 if (!result) {
    1936            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1937              :                                        spdm_context->transcript.digest_context_l1l2);
    1938            0 :                     spdm_context->transcript.digest_context_l1l2 = NULL;
    1939            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    1940              :                 }
    1941           62 :                 if ((spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >
    1942              :                     SPDM_MESSAGE_VERSION_11) {
    1943              : 
    1944              :                     /* Need append VCA since 1.2 script */
    1945           13 :                     result = libspdm_hash_update (
    1946              :                         spdm_context->connection_info.algorithm.base_hash_algo,
    1947              :                         spdm_context->transcript.digest_context_l1l2,
    1948           13 :                         libspdm_get_managed_buffer(
    1949           13 :                             &spdm_context->transcript.message_a),
    1950           13 :                         libspdm_get_managed_buffer_size(&spdm_context->transcript.
    1951              :                                                         message_a));
    1952           13 :                     if (!result) {
    1953            0 :                         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1954              :                                            spdm_context->transcript.digest_context_l1l2);
    1955            0 :                         spdm_context->transcript.digest_context_l1l2 = NULL;
    1956            0 :                         return LIBSPDM_STATUS_CRYPTO_ERROR;
    1957              :                     }
    1958              :                 }
    1959              :             }
    1960          718 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    1961              :                                           spdm_context->transcript.digest_context_l1l2, message,
    1962              :                                           message_size);
    1963          718 :             if (!result) {
    1964            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1965              :                                    spdm_context->transcript.digest_context_l1l2);
    1966            0 :                 spdm_context->transcript.digest_context_l1l2 = NULL;
    1967            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1968              :             }
    1969              :         } else {
    1970            4 :             if (spdm_session_info->session_transcript.digest_context_l1l2 == NULL) {
    1971            2 :                 spdm_session_info->session_transcript.digest_context_l1l2 = libspdm_hash_new (
    1972              :                     spdm_context->connection_info.algorithm.base_hash_algo);
    1973            2 :                 if (spdm_session_info->session_transcript.digest_context_l1l2 == NULL) {
    1974            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    1975              :                 }
    1976            2 :                 result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    1977              :                                             spdm_session_info->session_transcript.digest_context_l1l2);
    1978            2 :                 if (!result) {
    1979            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1980              :                                        spdm_session_info->session_transcript.digest_context_l1l2);
    1981            0 :                     spdm_session_info->session_transcript.digest_context_l1l2 = NULL;
    1982            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    1983              :                 }
    1984            2 :                 if ((spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >
    1985              :                     SPDM_MESSAGE_VERSION_11) {
    1986              : 
    1987              :                     /* Need append VCA since 1.2 script*/
    1988              : 
    1989            0 :                     result = libspdm_hash_update (
    1990              :                         spdm_context->connection_info.algorithm.base_hash_algo,
    1991              :                         spdm_session_info->session_transcript.digest_context_l1l2,
    1992            0 :                         libspdm_get_managed_buffer(
    1993            0 :                             &spdm_context->transcript.message_a),
    1994            0 :                         libspdm_get_managed_buffer_size(&spdm_context->transcript.
    1995              :                                                         message_a));
    1996            0 :                     if (!result) {
    1997            0 :                         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1998              :                                            spdm_session_info->session_transcript.digest_context_l1l2);
    1999            0 :                         spdm_session_info->session_transcript.digest_context_l1l2 = NULL;
    2000            0 :                         return LIBSPDM_STATUS_CRYPTO_ERROR;
    2001              :                     }
    2002              :                 }
    2003              :             }
    2004            4 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    2005              :                                           spdm_session_info->session_transcript.digest_context_l1l2,
    2006              :                                           message, message_size);
    2007            4 :             if (!result) {
    2008            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2009              :                                    spdm_session_info->session_transcript.digest_context_l1l2);
    2010            0 :                 spdm_session_info->session_transcript.digest_context_l1l2 = NULL;
    2011            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2012              :             }
    2013              :         }
    2014              : 
    2015          722 :         return LIBSPDM_STATUS_SUCCESS;
    2016              :     }
    2017              : #endif
    2018              : }
    2019              : 
    2020              : /**
    2021              :  * Append message K cache in SPDM context.
    2022              :  *
    2023              :  * @param  spdm_context                  A pointer to the SPDM context.
    2024              :  * @param  spdm_session_info              A pointer to the SPDM session context.
    2025              :  * @param  is_requester                  Indicate of the key generation for a requester or a responder.
    2026              :  * @param  message                      message buffer.
    2027              :  * @param  message_size                  size in bytes of message buffer.
    2028              :  *
    2029              :  * @return RETURN_SUCCESS          message is appended.
    2030              :  * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
    2031              :  **/
    2032          292 : libspdm_return_t libspdm_append_message_k(libspdm_context_t *spdm_context,
    2033              :                                           void *session_info,
    2034              :                                           bool is_requester, const void *message,
    2035              :                                           size_t message_size)
    2036              : {
    2037              :     libspdm_session_info_t *spdm_session_info;
    2038              : 
    2039          292 :     spdm_session_info = session_info;
    2040              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2041              :     return libspdm_append_managed_buffer(
    2042              :         &spdm_session_info->session_transcript.message_k, message,
    2043              :         message_size);
    2044              : #else
    2045              :     {
    2046              :         uint8_t *cert_chain_buffer;
    2047              :         size_t cert_chain_buffer_size;
    2048              :         bool result;
    2049              :         uint8_t cert_chain_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
    2050              :         uint32_t hash_size;
    2051              :         uint8_t slot_id;
    2052              : 
    2053          292 :         hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
    2054              : 
    2055          292 :         if (spdm_session_info->session_transcript.digest_context_th == NULL) {
    2056          150 :             if (!spdm_session_info->use_psk) {
    2057           88 :                 if (is_requester) {
    2058           58 :                     slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
    2059           58 :                     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
    2060           58 :                     if (slot_id == 0xFF) {
    2061            2 :                         result = libspdm_get_peer_public_key_buffer(
    2062              :                             spdm_context, (const void **)&cert_chain_buffer,
    2063              :                             &cert_chain_buffer_size);
    2064            2 :                         if (!result) {
    2065            0 :                             return LIBSPDM_STATUS_INVALID_STATE_PEER;
    2066              :                         }
    2067              : 
    2068            2 :                         result = libspdm_hash_all(
    2069              :                             spdm_context->connection_info.algorithm.base_hash_algo,
    2070              :                             cert_chain_buffer, cert_chain_buffer_size,
    2071              :                             cert_chain_buffer_hash);
    2072            2 :                         if (!result) {
    2073            0 :                             return LIBSPDM_STATUS_CRYPTO_ERROR;
    2074              :                         }
    2075              :                     } else {
    2076           56 :                         LIBSPDM_ASSERT(
    2077              :                             hash_size ==
    2078              :                             spdm_context->connection_info
    2079              :                             .peer_used_cert_chain[slot_id].buffer_hash_size);
    2080              : 
    2081           56 :                         libspdm_copy_mem(cert_chain_buffer_hash,
    2082              :                                          sizeof(cert_chain_buffer_hash),
    2083              :                                          spdm_context->connection_info
    2084           56 :                                          .peer_used_cert_chain[slot_id].buffer_hash,
    2085              :                                          hash_size);
    2086              :                     }
    2087              :                 } else {
    2088           30 :                     slot_id = spdm_context->connection_info.local_used_cert_chain_slot_id;
    2089           30 :                     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
    2090           30 :                     if (slot_id == 0xFF) {
    2091            2 :                         result = libspdm_get_local_public_key_buffer(
    2092              :                             spdm_context, (const void **)&cert_chain_buffer,
    2093              :                             &cert_chain_buffer_size);
    2094              :                     } else {
    2095           28 :                         result = libspdm_get_local_cert_chain_buffer(
    2096              :                             spdm_context, (const void **)&cert_chain_buffer,
    2097              :                             &cert_chain_buffer_size);
    2098              :                     }
    2099           30 :                     if (!result) {
    2100            0 :                         return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
    2101              :                     }
    2102              : 
    2103           30 :                     result = libspdm_hash_all(
    2104              :                         spdm_context->connection_info.algorithm.base_hash_algo,
    2105              :                         cert_chain_buffer, cert_chain_buffer_size,
    2106              :                         cert_chain_buffer_hash);
    2107           30 :                     if (!result) {
    2108            0 :                         return LIBSPDM_STATUS_CRYPTO_ERROR;
    2109              :                     }
    2110              :                 }
    2111              :             }
    2112              :         }
    2113              : 
    2114              : 
    2115              :         /* prepare digest_context_th*/
    2116              : 
    2117          292 :         if (spdm_session_info->session_transcript.digest_context_th == NULL) {
    2118          150 :             spdm_session_info->session_transcript.digest_context_th = libspdm_hash_new (
    2119              :                 spdm_context->connection_info.algorithm.base_hash_algo);
    2120          150 :             if (spdm_session_info->session_transcript.digest_context_th == NULL) {
    2121            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2122              :             }
    2123          150 :             result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    2124              :                                         spdm_session_info->session_transcript.digest_context_th);
    2125          150 :             if (!result) {
    2126            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2127              :                                    spdm_session_info->session_transcript.digest_context_th);
    2128            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2129              :             }
    2130          150 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    2131              :                                           spdm_session_info->session_transcript.digest_context_th,
    2132          150 :                                           libspdm_get_managed_buffer(&spdm_context->transcript.
    2133              :                                                                      message_a),
    2134              :                                           libspdm_get_managed_buffer_size(
    2135          150 :                                               &spdm_context->transcript.message_a));
    2136          150 :             if (!result) {
    2137            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2138              :                                    spdm_session_info->session_transcript.digest_context_th);
    2139            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2140              :             }
    2141          150 :             if (!spdm_session_info->use_psk) {
    2142           88 :                 if (spdm_context->connection_info.multi_key_conn_rsp) {
    2143            0 :                     result = libspdm_hash_update (
    2144              :                         spdm_context->connection_info.algorithm.base_hash_algo,
    2145              :                         spdm_session_info->session_transcript.digest_context_th,
    2146            0 :                         libspdm_get_managed_buffer(&spdm_context->transcript.message_d),
    2147            0 :                         libspdm_get_managed_buffer_size(&spdm_context->transcript.message_d));
    2148            0 :                     if (!result) {
    2149            0 :                         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2150              :                                            spdm_session_info->session_transcript.digest_context_th);
    2151            0 :                         return LIBSPDM_STATUS_CRYPTO_ERROR;
    2152              :                     }
    2153              :                 }
    2154              : 
    2155           88 :                 result = libspdm_hash_update (
    2156              :                     spdm_context->connection_info.algorithm.base_hash_algo,
    2157              :                     spdm_session_info->session_transcript.digest_context_th,
    2158              :                     cert_chain_buffer_hash, hash_size);
    2159           88 :                 if (!result) {
    2160            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2161              :                                        spdm_session_info->session_transcript.digest_context_th);
    2162            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2163              :                 }
    2164              :             }
    2165              :         }
    2166          292 :         result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    2167              :                                       spdm_session_info->session_transcript.digest_context_th,
    2168              :                                       message,
    2169              :                                       message_size);
    2170          292 :         if (!result) {
    2171            0 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2172              :                                spdm_session_info->session_transcript.digest_context_th);
    2173            0 :             return LIBSPDM_STATUS_CRYPTO_ERROR;
    2174              :         }
    2175          292 :         return LIBSPDM_STATUS_SUCCESS;
    2176              :     }
    2177              : #endif
    2178              : }
    2179              : 
    2180              : /**
    2181              :  * Append message EncapD cache in SPDM context.
    2182              :  *
    2183              :  * @param  spdm_context       A pointer to the SPDM context.
    2184              :  * @param  spdm_session_info  A pointer to the SPDM session context.
    2185              :  * @param  is_requester       Indicate of the key generation for a requester or a responder.
    2186              :  * @param  message            Message buffer.
    2187              :  * @param  message_size       Size in bytes of message buffer.
    2188              :  *
    2189              :  * @return RETURN_SUCCESS          message is appended.
    2190              :  * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
    2191              :  **/
    2192            4 : libspdm_return_t libspdm_append_message_encap_d(libspdm_context_t *spdm_context,
    2193              :                                                 void *session_info,
    2194              :                                                 bool is_requester, const void *message,
    2195              :                                                 size_t message_size)
    2196              : {
    2197              :     libspdm_session_info_t *spdm_session_info;
    2198              : 
    2199            4 :     spdm_session_info = session_info;
    2200              :     /* Only the first message EncapD in current session counts  */
    2201            4 :     if (libspdm_get_managed_buffer_size(&spdm_session_info->session_transcript.message_encap_d) !=
    2202              :         0) {
    2203            0 :         return LIBSPDM_STATUS_SUCCESS;
    2204              :     }
    2205            4 :     return libspdm_append_managed_buffer(
    2206            4 :         &spdm_session_info->session_transcript.message_encap_d, message,
    2207              :         message_size);
    2208              : }
    2209              : 
    2210              : /**
    2211              :  * Append message F cache in SPDM context.
    2212              :  *
    2213              :  * @param  spdm_context                  A pointer to the SPDM context.
    2214              :  * @param  spdm_session_info              A pointer to the SPDM session context.
    2215              :  * @param  is_requester                  Indicate of the key generation for a requester or a responder.
    2216              :  * @param  message                      message buffer.
    2217              :  * @param  message_size                  size in bytes of message buffer.
    2218              :  *
    2219              :  * @return RETURN_SUCCESS          message is appended.
    2220              :  * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
    2221              :  **/
    2222          241 : libspdm_return_t libspdm_append_message_f(libspdm_context_t *spdm_context,
    2223              :                                           void *session_info,
    2224              :                                           bool is_requester, const void *message,
    2225              :                                           size_t message_size)
    2226              : {
    2227              :     libspdm_session_info_t *spdm_session_info;
    2228              : 
    2229          241 :     spdm_session_info = session_info;
    2230              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2231              :     return libspdm_append_managed_buffer(
    2232              :         &spdm_session_info->session_transcript.message_f, message,
    2233              :         message_size);
    2234              : #else
    2235              :     {
    2236              :         const uint8_t *mut_cert_chain_buffer;
    2237              :         size_t mut_cert_chain_buffer_size;
    2238              :         bool result;
    2239              :         uint8_t mut_cert_chain_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
    2240              :         uint32_t hash_size;
    2241              :         libspdm_return_t status;
    2242              :         uint8_t slot_id;
    2243              : 
    2244          241 :         hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
    2245              : 
    2246          241 :         if (!spdm_session_info->session_transcript.message_f_initialized) {
    2247              :             /* digest_context_th might be NULL in unit test, where message_k is hardcoded. */
    2248           92 :             if (spdm_session_info->session_transcript.digest_context_th == NULL) {
    2249              :                 status =
    2250           91 :                     libspdm_append_message_k (spdm_context, session_info, is_requester, NULL, 0);
    2251           91 :                 if (LIBSPDM_STATUS_IS_ERROR(status)) {
    2252            0 :                     return status;
    2253              :                 }
    2254              :             }
    2255              : 
    2256           92 :             if (!spdm_session_info->use_psk && (spdm_session_info->mut_auth_requested != 0)) {
    2257           16 :                 if (is_requester) {
    2258            5 :                     slot_id = spdm_context->connection_info.local_used_cert_chain_slot_id;
    2259            5 :                     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
    2260            5 :                     if (slot_id == 0xFF) {
    2261            0 :                         result = libspdm_get_local_public_key_buffer(
    2262              :                             spdm_context,
    2263              :                             (const void **)&mut_cert_chain_buffer,
    2264              :                             &mut_cert_chain_buffer_size);
    2265              :                     } else {
    2266            5 :                         result = libspdm_get_local_cert_chain_buffer(
    2267              :                             spdm_context,
    2268              :                             (const void **)&mut_cert_chain_buffer,
    2269              :                             &mut_cert_chain_buffer_size);
    2270              :                     }
    2271            5 :                     if (!result) {
    2272            0 :                         return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
    2273              :                     }
    2274              : 
    2275            5 :                     result = libspdm_hash_all(
    2276              :                         spdm_context->connection_info.algorithm.base_hash_algo,
    2277              :                         mut_cert_chain_buffer, mut_cert_chain_buffer_size,
    2278              :                         mut_cert_chain_buffer_hash);
    2279            5 :                     if (!result) {
    2280            0 :                         return LIBSPDM_STATUS_CRYPTO_ERROR;
    2281              :                     }
    2282              :                 } else {
    2283           11 :                     slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
    2284           11 :                     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
    2285           11 :                     if (slot_id == 0xFF) {
    2286            1 :                         result = libspdm_get_peer_public_key_buffer(
    2287              :                             spdm_context,
    2288              :                             (const void **)&mut_cert_chain_buffer,
    2289              :                             &mut_cert_chain_buffer_size);
    2290            1 :                         if (!result) {
    2291            0 :                             return LIBSPDM_STATUS_INVALID_STATE_PEER;
    2292              :                         }
    2293              : 
    2294            1 :                         result = libspdm_hash_all(
    2295              :                             spdm_context->connection_info.algorithm.base_hash_algo,
    2296              :                             mut_cert_chain_buffer, mut_cert_chain_buffer_size,
    2297              :                             mut_cert_chain_buffer_hash);
    2298            1 :                         if (!result) {
    2299            0 :                             return LIBSPDM_STATUS_CRYPTO_ERROR;
    2300              :                         }
    2301              :                     } else {
    2302           10 :                         LIBSPDM_ASSERT(
    2303              :                             hash_size ==
    2304              :                             spdm_context->connection_info
    2305              :                             .peer_used_cert_chain[slot_id].buffer_hash_size);
    2306              : 
    2307           10 :                         libspdm_copy_mem(mut_cert_chain_buffer_hash,
    2308              :                                          sizeof(mut_cert_chain_buffer_hash),
    2309              :                                          spdm_context->connection_info
    2310           10 :                                          .peer_used_cert_chain[slot_id].buffer_hash,
    2311              :                                          hash_size);
    2312              :                     }
    2313              :                 }
    2314              :             }
    2315              : 
    2316              :             /* It is first time call, backup current message_k context
    2317              :              * this backup will be used in reset_message_f.*/
    2318              : 
    2319           92 :             LIBSPDM_ASSERT (spdm_session_info->session_transcript.digest_context_th != NULL);
    2320           92 :             spdm_session_info->session_transcript.digest_context_th_backup = libspdm_hash_new (
    2321              :                 spdm_context->connection_info.algorithm.base_hash_algo);
    2322           92 :             if (spdm_session_info->session_transcript.digest_context_th_backup == NULL) {
    2323            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2324              :             }
    2325           92 :             result = libspdm_hash_duplicate (spdm_context->connection_info.algorithm.base_hash_algo,
    2326           92 :                                              spdm_session_info->session_transcript.digest_context_th,
    2327              :                                              spdm_session_info->session_transcript.digest_context_th_backup);
    2328           92 :             if (!result) {
    2329            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2330              :                                    spdm_session_info->session_transcript.digest_context_th_backup);
    2331            0 :                 spdm_session_info->session_transcript.digest_context_th_backup = NULL;
    2332            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2333              :             }
    2334              :         }
    2335              : 
    2336              : 
    2337              :         /* prepare digest_context_th*/
    2338              : 
    2339          241 :         LIBSPDM_ASSERT (spdm_session_info->session_transcript.digest_context_th != NULL);
    2340          241 :         if (!spdm_session_info->session_transcript.message_f_initialized) {
    2341           92 :             if (!spdm_session_info->use_psk && (spdm_session_info->mut_auth_requested != 0)) {
    2342           16 :                 if (spdm_context->connection_info.multi_key_conn_req) {
    2343            0 :                     result = libspdm_hash_update (
    2344              :                         spdm_context->connection_info.algorithm.base_hash_algo,
    2345              :                         spdm_session_info->session_transcript.digest_context_th,
    2346            0 :                         libspdm_get_managed_buffer(&spdm_session_info->session_transcript.
    2347              :                                                    message_encap_d),
    2348            0 :                         libspdm_get_managed_buffer_size(&spdm_session_info->session_transcript.
    2349              :                                                         message_encap_d));
    2350            0 :                     if (!result) {
    2351            0 :                         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2352              :                                            spdm_session_info->session_transcript.digest_context_th);
    2353            0 :                         spdm_session_info->session_transcript.digest_context_th = NULL;
    2354            0 :                         return LIBSPDM_STATUS_CRYPTO_ERROR;
    2355              :                     }
    2356              :                 }
    2357              : 
    2358           16 :                 result = libspdm_hash_update (
    2359              :                     spdm_context->connection_info.algorithm.base_hash_algo,
    2360              :                     spdm_session_info->session_transcript.digest_context_th,
    2361              :                     mut_cert_chain_buffer_hash, hash_size);
    2362           16 :                 if (!result) {
    2363            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2364              :                                        spdm_session_info->session_transcript.digest_context_th);
    2365            0 :                     spdm_session_info->session_transcript.digest_context_th = NULL;
    2366            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2367              :                 }
    2368              :             }
    2369              :         }
    2370          241 :         result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    2371              :                                       spdm_session_info->session_transcript.digest_context_th,
    2372              :                                       message,
    2373              :                                       message_size);
    2374          241 :         if (!result) {
    2375            0 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2376              :                                spdm_session_info->session_transcript.digest_context_th);
    2377            0 :             spdm_session_info->session_transcript.digest_context_th = NULL;
    2378            0 :             return LIBSPDM_STATUS_CRYPTO_ERROR;
    2379              :         }
    2380              : 
    2381          241 :         spdm_session_info->session_transcript.message_f_initialized = true;
    2382          241 :         return LIBSPDM_STATUS_SUCCESS;
    2383              :     }
    2384              : #endif
    2385              : }
    2386              : 
    2387              : /**
    2388              :  * Append message E cache in SPDM context.
    2389              :  * If session_info is NULL, this function will use E cache of SPDM context,
    2390              :  * else will use E cache of SPDM session context.
    2391              :  *
    2392              :  * @param  spdm_context                  A pointer to the SPDM context.
    2393              :  * @param  session_info                  A pointer to the SPDM session context.
    2394              :  * @param  message                      message buffer.
    2395              :  * @param  message_size                  size in bytes of message buffer.
    2396              :  *
    2397              :  * @return RETURN_SUCCESS          message is appended.
    2398              :  * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
    2399              :  **/
    2400           34 : libspdm_return_t libspdm_append_message_e(libspdm_context_t *spdm_context, void *session_info,
    2401              :                                           const void *message, size_t message_size)
    2402              : {
    2403              :     libspdm_session_info_t *spdm_session_info;
    2404              : 
    2405           34 :     spdm_session_info = session_info;
    2406              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2407              :     if (spdm_session_info == NULL) {
    2408              :         return libspdm_append_managed_buffer(&spdm_context->transcript.message_e,
    2409              :                                              message, message_size);
    2410              :     } else {
    2411              :         return libspdm_append_managed_buffer(&spdm_session_info->session_transcript.message_e,
    2412              :                                              message, message_size);
    2413              :     }
    2414              : #else
    2415              :     {
    2416              :         bool result;
    2417              : 
    2418           34 :         if (spdm_session_info == NULL) {
    2419           28 :             if (spdm_context->transcript.digest_context_il1il2 == NULL) {
    2420           14 :                 spdm_context->transcript.digest_context_il1il2 = libspdm_hash_new (
    2421              :                     spdm_context->connection_info.algorithm.base_hash_algo);
    2422           14 :                 if (spdm_context->transcript.digest_context_il1il2 == NULL) {
    2423            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2424              :                 }
    2425           14 :                 result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    2426              :                                             spdm_context->transcript.digest_context_il1il2);
    2427           14 :                 if (!result) {
    2428            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2429              :                                        spdm_context->transcript.digest_context_il1il2);
    2430            0 :                     spdm_context->transcript.digest_context_il1il2 = NULL;
    2431            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2432              :                 }
    2433              : 
    2434           14 :                 result = libspdm_hash_update (
    2435              :                     spdm_context->connection_info.algorithm.base_hash_algo,
    2436              :                     spdm_context->transcript.digest_context_il1il2,
    2437           14 :                     libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
    2438           14 :                     libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
    2439              : 
    2440           14 :                 if (!result) {
    2441            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2442              :                                        spdm_context->transcript.digest_context_il1il2);
    2443            0 :                     spdm_context->transcript.digest_context_il1il2 = NULL;
    2444            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2445              :                 }
    2446              :             }
    2447           28 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    2448              :                                           spdm_context->transcript.digest_context_il1il2, message,
    2449              :                                           message_size);
    2450           28 :             if (!result) {
    2451            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2452              :                                    spdm_context->transcript.digest_context_il1il2);
    2453            0 :                 spdm_context->transcript.digest_context_il1il2 = NULL;
    2454            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2455              :             }
    2456              :         } else {
    2457            6 :             if (spdm_session_info->session_transcript.digest_context_il1il2 == NULL) {
    2458            3 :                 spdm_session_info->session_transcript.digest_context_il1il2 = libspdm_hash_new (
    2459              :                     spdm_context->connection_info.algorithm.base_hash_algo);
    2460            3 :                 if (spdm_session_info->session_transcript.digest_context_il1il2 == NULL) {
    2461            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2462              :                 }
    2463            3 :                 result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    2464              :                                             spdm_session_info->session_transcript.digest_context_il1il2);
    2465            3 :                 if (!result) {
    2466            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2467              :                                        spdm_session_info->session_transcript.digest_context_il1il2);
    2468            0 :                     spdm_session_info->session_transcript.digest_context_il1il2 = NULL;
    2469            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2470              :                 }
    2471              : 
    2472            3 :                 result = libspdm_hash_update (
    2473              :                     spdm_context->connection_info.algorithm.base_hash_algo,
    2474              :                     spdm_session_info->session_transcript.digest_context_il1il2,
    2475            3 :                     libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
    2476            3 :                     libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
    2477              : 
    2478            3 :                 if (!result) {
    2479            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2480              :                                        spdm_session_info->session_transcript.digest_context_il1il2);
    2481            0 :                     spdm_session_info->session_transcript.digest_context_il1il2 = NULL;
    2482            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2483              :                 }
    2484              :             }
    2485            6 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    2486              :                                           spdm_session_info->session_transcript.digest_context_il1il2,
    2487              :                                           message, message_size);
    2488            6 :             if (!result) {
    2489            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2490              :                                    spdm_session_info->session_transcript.digest_context_il1il2);
    2491            0 :                 spdm_session_info->session_transcript.digest_context_il1il2 = NULL;
    2492            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2493              :             }
    2494              :         }
    2495              : 
    2496           34 :         return LIBSPDM_STATUS_SUCCESS;
    2497              :     }
    2498              : #endif
    2499              : }
    2500              : 
    2501              : /**
    2502              :  * Append message encap E cache in SPDM context.
    2503              :  * If session_info is NULL, this function will use encap E cache of SPDM context,
    2504              :  * else will use encap E cache of SPDM session context.
    2505              :  *
    2506              :  * @param  spdm_context                  A pointer to the SPDM context.
    2507              :  * @param  session_info                  A pointer to the SPDM session context.
    2508              :  * @param  message                      message buffer.
    2509              :  * @param  message_size                  size in bytes of message buffer.
    2510              :  *
    2511              :  * @return RETURN_SUCCESS          message is appended.
    2512              :  * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
    2513              :  **/
    2514           24 : libspdm_return_t libspdm_append_message_encap_e(libspdm_context_t *spdm_context, void *session_info,
    2515              :                                                 const void *message, size_t message_size)
    2516              : {
    2517              :     libspdm_session_info_t *spdm_session_info;
    2518              : 
    2519           24 :     spdm_session_info = session_info;
    2520              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2521              :     if (spdm_session_info == NULL) {
    2522              :         return libspdm_append_managed_buffer(&spdm_context->transcript.message_encap_e,
    2523              :                                              message, message_size);
    2524              :     } else {
    2525              :         return libspdm_append_managed_buffer(&spdm_session_info->session_transcript.message_encap_e,
    2526              :                                              message, message_size);
    2527              :     }
    2528              : #else
    2529              :     {
    2530              :         bool result;
    2531              : 
    2532           24 :         if (spdm_session_info == NULL) {
    2533           19 :             if (spdm_context->transcript.digest_context_encap_il1il2 == NULL) {
    2534           12 :                 spdm_context->transcript.digest_context_encap_il1il2 = libspdm_hash_new (
    2535              :                     spdm_context->connection_info.algorithm.base_hash_algo);
    2536           12 :                 if (spdm_context->transcript.digest_context_encap_il1il2 == NULL) {
    2537            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2538              :                 }
    2539           12 :                 result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    2540              :                                             spdm_context->transcript.digest_context_encap_il1il2);
    2541           12 :                 if (!result) {
    2542            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2543              :                                        spdm_context->transcript.digest_context_encap_il1il2);
    2544            0 :                     spdm_context->transcript.digest_context_encap_il1il2 = NULL;
    2545            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2546              :                 }
    2547              : 
    2548           12 :                 result = libspdm_hash_update (
    2549              :                     spdm_context->connection_info.algorithm.base_hash_algo,
    2550              :                     spdm_context->transcript.digest_context_encap_il1il2,
    2551           12 :                     libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
    2552           12 :                     libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
    2553              : 
    2554           12 :                 if (!result) {
    2555            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2556              :                                        spdm_context->transcript.digest_context_encap_il1il2);
    2557            0 :                     spdm_context->transcript.digest_context_encap_il1il2 = NULL;
    2558            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2559              :                 }
    2560              :             }
    2561           19 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    2562              :                                           spdm_context->transcript.digest_context_encap_il1il2,
    2563              :                                           message,
    2564              :                                           message_size);
    2565           19 :             if (!result) {
    2566            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2567              :                                    spdm_context->transcript.digest_context_encap_il1il2);
    2568            0 :                 spdm_context->transcript.digest_context_encap_il1il2 = NULL;
    2569            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2570              :             }
    2571              :         } else {
    2572            5 :             if (spdm_session_info->session_transcript.digest_context_encap_il1il2 == NULL) {
    2573            3 :                 spdm_session_info->session_transcript.digest_context_encap_il1il2 =
    2574            3 :                     libspdm_hash_new (spdm_context->connection_info.algorithm.base_hash_algo);
    2575            3 :                 if (spdm_session_info->session_transcript.digest_context_encap_il1il2 == NULL) {
    2576            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2577              :                 }
    2578            3 :                 result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    2579              :                                             spdm_session_info->session_transcript.digest_context_encap_il1il2);
    2580            3 :                 if (!result) {
    2581            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2582              :                                        spdm_session_info->session_transcript.digest_context_encap_il1il2);
    2583            0 :                     spdm_session_info->session_transcript.digest_context_encap_il1il2 = NULL;
    2584            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2585              :                 }
    2586              : 
    2587            3 :                 result = libspdm_hash_update (
    2588              :                     spdm_context->connection_info.algorithm.base_hash_algo,
    2589              :                     spdm_session_info->session_transcript.digest_context_encap_il1il2,
    2590            3 :                     libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
    2591            3 :                     libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
    2592              : 
    2593            3 :                 if (!result) {
    2594            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2595              :                                        spdm_session_info->session_transcript.digest_context_encap_il1il2);
    2596            0 :                     spdm_session_info->session_transcript.digest_context_encap_il1il2 = NULL;
    2597            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2598              :                 }
    2599              :             }
    2600            5 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    2601              :                                           spdm_session_info->session_transcript.digest_context_encap_il1il2,
    2602              :                                           message, message_size);
    2603            5 :             if (!result) {
    2604            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2605              :                                    spdm_session_info->session_transcript.digest_context_encap_il1il2);
    2606            0 :                 spdm_session_info->session_transcript.digest_context_encap_il1il2 = NULL;
    2607            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2608              :             }
    2609              :         }
    2610              : 
    2611           24 :         return LIBSPDM_STATUS_SUCCESS;
    2612              :     }
    2613              : #endif
    2614              : }
    2615              : /**
    2616              :  * This function returns if a given version is supported based upon the GET_VERSION/VERSION.
    2617              :  *
    2618              :  * @param  spdm_context                  A pointer to the SPDM context.
    2619              :  * @param  version                      The SPDM version.
    2620              :  *
    2621              :  * @retval true  the version is supported.
    2622              :  * @retval false the version is not supported.
    2623              :  **/
    2624            0 : bool libspdm_is_version_supported(const libspdm_context_t *spdm_context, uint8_t version)
    2625              : {
    2626            0 :     if (version == (spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT)) {
    2627            0 :         return true;
    2628              :     }
    2629              : 
    2630            0 :     return false;
    2631              : }
    2632              : 
    2633              : /**
    2634              :  * This function returns connection version negotiated by GET_VERSION/VERSION.
    2635              :  *
    2636              :  * @param  spdm_context                  A pointer to the SPDM context.
    2637              :  *
    2638              :  * @return the connection version.
    2639              :  **/
    2640       141634 : uint8_t libspdm_get_connection_version(const libspdm_context_t *spdm_context)
    2641              : {
    2642       141634 :     return (uint8_t)(spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT);
    2643              : }
    2644              : 
    2645              : /**
    2646              :  * This function returns if a capabilities flag is supported in current SPDM connection.
    2647              :  *
    2648              :  * @param  spdm_context                  A pointer to the SPDM context.
    2649              :  * @param  is_requester                  Is the function called from a requester.
    2650              :  * @param  requester_capabilities_flag    The requester capabilities flag to be checked
    2651              :  * @param  responder_capabilities_flag    The responder capabilities flag to be checked
    2652              :  *
    2653              :  * @retval true  the capabilities flag is supported.
    2654              :  * @retval false the capabilities flag is not supported.
    2655              :  **/
    2656        76689 : bool libspdm_is_capabilities_flag_supported(const libspdm_context_t *spdm_context,
    2657              :                                             bool is_requester,
    2658              :                                             uint32_t requester_capabilities_flag,
    2659              :                                             uint32_t responder_capabilities_flag)
    2660              : {
    2661              :     uint32_t negotiated_requester_capabilities_flag;
    2662              :     uint32_t negotiated_responder_capabilities_flag;
    2663              : 
    2664        76689 :     if (is_requester) {
    2665        72288 :         negotiated_requester_capabilities_flag = spdm_context->local_context.capability.flags;
    2666        72288 :         negotiated_responder_capabilities_flag = spdm_context->connection_info.capability.flags;
    2667              :     } else {
    2668         4401 :         negotiated_requester_capabilities_flag = spdm_context->connection_info.capability.flags;
    2669         4401 :         negotiated_responder_capabilities_flag = spdm_context->local_context.capability.flags;
    2670              :     }
    2671              : 
    2672        76689 :     if (((requester_capabilities_flag == 0) ||
    2673        73057 :          ((negotiated_requester_capabilities_flag &
    2674        71723 :            requester_capabilities_flag) != 0)) &&
    2675        70267 :         ((responder_capabilities_flag == 0) ||
    2676        70267 :          ((negotiated_responder_capabilities_flag &
    2677              :            responder_capabilities_flag) != 0))) {
    2678        70858 :         return true;
    2679              :     } else {
    2680         5831 :         return false;
    2681              :     }
    2682              : }
    2683              : 
    2684           31 : bool libspdm_is_encap_supported(const libspdm_context_t *spdm_context)
    2685              : {
    2686           31 :     if (libspdm_get_connection_version(spdm_context) == SPDM_MESSAGE_VERSION_10) {
    2687            0 :         return false;
    2688           31 :     } else if (libspdm_get_connection_version(spdm_context) == SPDM_MESSAGE_VERSION_12) {
    2689              :         /* ENCAP_CAP was erroneously deprecated in SPDM 1.2.0 and 1.2.1, and MUT_AUTH_CAP
    2690              :          * was used in its place. In SPDM 1.2.2 and later ENCAP_CAP is undeprecated. Since
    2691              :          * UpdateVersionNumber must be ignored when checking interoperability libspdm will check
    2692              :          * if ENCAP_CAP or MUT_AUTH_CAP is set. */
    2693            2 :         const bool is_req_encap_cap_supported = libspdm_is_capabilities_flag_supported(
    2694            2 :             spdm_context, spdm_context->local_context.is_requester,
    2695              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP, 0);
    2696            2 :         const bool is_req_mut_auth_cap_supported = libspdm_is_capabilities_flag_supported(
    2697            2 :             spdm_context, spdm_context->local_context.is_requester,
    2698              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP, 0);
    2699            2 :         const bool is_rsp_encap_cap_supported = libspdm_is_capabilities_flag_supported(
    2700            2 :             spdm_context, spdm_context->local_context.is_requester,
    2701              :             0, SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCAP_CAP);
    2702            2 :         const bool is_rsp_mut_auth_cap_supported = libspdm_is_capabilities_flag_supported(
    2703            2 :             spdm_context, spdm_context->local_context.is_requester,
    2704              :             0, SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP);
    2705              : 
    2706            2 :         return ((is_req_encap_cap_supported || is_req_mut_auth_cap_supported) &&
    2707            0 :                 (is_rsp_encap_cap_supported || is_rsp_mut_auth_cap_supported));
    2708              :     } else {
    2709              :         /* For SPDM 1.1 and 1.3 and later only check ENCAP_CAP. */
    2710           29 :         return libspdm_is_capabilities_flag_supported(
    2711           29 :             spdm_context, spdm_context->local_context.is_requester,
    2712              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP,
    2713              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCAP_CAP);
    2714              :     }
    2715              : }
    2716              : 
    2717              : /**
    2718              :  * Register SPDM device input/output functions.
    2719              :  *
    2720              :  * This function must be called after libspdm_init_context, and before any SPDM communication.
    2721              :  *
    2722              :  * @param  spdm_context                  A pointer to the SPDM context.
    2723              :  * @param  send_message                  The function to send an SPDM transport layer message.
    2724              :  * @param  receive_message               The function to receive an SPDM transport layer message.
    2725              :  **/
    2726           99 : void libspdm_register_device_io_func(
    2727              :     void *spdm_context, libspdm_device_send_message_func send_message,
    2728              :     libspdm_device_receive_message_func receive_message)
    2729              : {
    2730              :     libspdm_context_t *context;
    2731              : 
    2732           99 :     context = spdm_context;
    2733           99 :     context->send_message = send_message;
    2734           99 :     context->receive_message = receive_message;
    2735           99 : }
    2736              : 
    2737              : /**
    2738              :  * Register SPDM device buffer management functions.
    2739              :  *
    2740              :  * This function must be called after libspdm_init_context, and before any SPDM communication.
    2741              :  *
    2742              :  * The sender_buffer_size and receiver_buffer_size must be no smaller than
    2743              :  * MAX (non-secure Transport Message Header Size +
    2744              :  *          SPDM_CAPABILITIES.DataTransferSize +
    2745              :  *          max alignment pad size (transport specific),
    2746              :  *      secure Transport Message Header Size +
    2747              :  *          sizeof(spdm_secured_message_a_data_header1_t) +
    2748              :  *          length of sequence_number (transport specific) +
    2749              :  *          sizeof(spdm_secured_message_a_data_header2_t) +
    2750              :  *          sizeof(spdm_secured_message_cipher_header_t) +
    2751              :  *          App Message Header Size (transport specific) +
    2752              :  *          SPDM_CAPABILITIES.DataTransferSize +
    2753              :  *          maximum random data size (transport specific) +
    2754              :  *          AEAD MAC size (16) +
    2755              :  *          max alignment pad size (transport specific)).
    2756              :  *
    2757              :  * Finally, the SPDM_CAPABILITIES.DataTransferSize will be calculated based upon it.
    2758              :  *
    2759              :  *   For MCTP,
    2760              :  *          Transport Message Header Size = sizeof(mctp_message_header_t)
    2761              :  *          length of sequence_number = 2
    2762              :  *          App Message Header Size = sizeof(mctp_message_header_t)
    2763              :  *          maximum random data size = MCTP_MAX_RANDOM_NUMBER_COUNT
    2764              :  *          max alignment pad size = 0
    2765              :  *   For PCI_DOE,
    2766              :  *          Transport Message Header Size = sizeof(pci_doe_data_object_header_t)
    2767              :  *          length of sequence_number = 0
    2768              :  *          App Message Header Size = 0
    2769              :  *          maximum random data size = 0
    2770              :  *          max alignment pad size = 3
    2771              :  *
    2772              :  * @param  spdm_context                  A pointer to the SPDM context.
    2773              :  * @param  sender_buffer_size            Size in bytes of the sender buffer.
    2774              :  * @param  receiver_buffer_size          Size in bytes of the receiver buffer.
    2775              :  * @param  acquire_sender_buffer         The function to acquire transport layer sender buffer.
    2776              :  * @param  release_sender_buffer         The function to release transport layer sender buffer.
    2777              :  * @param  acquire_receiver_buffer       The function to acquire transport layer receiver buffer.
    2778              :  * @param  release_receiver_buffer       The function to release transport layer receiver buffer.
    2779              :  **/
    2780          100 : void libspdm_register_device_buffer_func(
    2781              :     void *spdm_context,
    2782              :     uint32_t sender_buffer_size,
    2783              :     uint32_t receiver_buffer_size,
    2784              :     libspdm_device_acquire_sender_buffer_func acquire_sender_buffer,
    2785              :     libspdm_device_release_sender_buffer_func release_sender_buffer,
    2786              :     libspdm_device_acquire_receiver_buffer_func acquire_receiver_buffer,
    2787              :     libspdm_device_release_receiver_buffer_func release_receiver_buffer)
    2788              : {
    2789              :     libspdm_context_t *context;
    2790              : 
    2791          100 :     context = spdm_context;
    2792          100 :     context->sender_buffer_size = sender_buffer_size;
    2793          100 :     context->receiver_buffer_size = receiver_buffer_size;
    2794          100 :     context->acquire_sender_buffer = acquire_sender_buffer;
    2795          100 :     context->release_sender_buffer = release_sender_buffer;
    2796          100 :     context->acquire_receiver_buffer = acquire_receiver_buffer;
    2797          100 :     context->release_receiver_buffer = release_receiver_buffer;
    2798              : 
    2799          100 :     LIBSPDM_ASSERT (sender_buffer_size >=
    2800              :                     context->local_context.capability.transport_header_size +
    2801              :                     context->local_context.capability.transport_tail_size);
    2802          100 :     sender_buffer_size -= (context->local_context.capability.transport_header_size +
    2803          100 :                            context->local_context.capability.transport_tail_size);
    2804          100 :     LIBSPDM_ASSERT (sender_buffer_size >= SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12);
    2805          100 :     context->local_context.capability.sender_data_transfer_size = sender_buffer_size;
    2806              : 
    2807          100 :     LIBSPDM_ASSERT(receiver_buffer_size >=
    2808              :                    context->local_context.capability.transport_header_size +
    2809              :                    context->local_context.capability.transport_tail_size);
    2810          100 :     receiver_buffer_size -= (context->local_context.capability.transport_header_size +
    2811          100 :                              context->local_context.capability.transport_tail_size);
    2812          100 :     LIBSPDM_ASSERT (receiver_buffer_size >= SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12);
    2813          100 :     context->local_context.capability.data_transfer_size = receiver_buffer_size;
    2814          100 : }
    2815              : 
    2816              : /**
    2817              :  * Register SPDM transport layer encode/decode functions for SPDM or APP messages.
    2818              :  *
    2819              :  * This function must be called after libspdm_init_context, and before any SPDM communication.
    2820              :  *
    2821              :  * @param  spdm_context                  A pointer to the SPDM context.
    2822              :  * @param  transport_encode_message       The function to encode an SPDM or APP message to a transport layer message.
    2823              :  * @param  transport_decode_message       The function to decode an SPDM or APP message from a transport layer message.
    2824              :  **/
    2825          101 : void libspdm_register_transport_layer_func(
    2826              :     void *spdm_context,
    2827              :     uint32_t max_spdm_msg_size,
    2828              :     uint32_t transport_header_size,
    2829              :     uint32_t transport_tail_size,
    2830              :     libspdm_transport_encode_message_func transport_encode_message,
    2831              :     libspdm_transport_decode_message_func transport_decode_message)
    2832              : {
    2833              :     libspdm_context_t *context;
    2834              : 
    2835          101 :     context = spdm_context;
    2836              : 
    2837              :     /* fix the data_transfer_size if it is set before */
    2838          101 :     if ((context->local_context.capability.data_transfer_size != 0) &&
    2839            1 :         (context->local_context.capability.data_transfer_size ==
    2840            1 :          context->receiver_buffer_size)) {
    2841            0 :         context->local_context.capability.data_transfer_size =
    2842            0 :             (uint32_t)(context->receiver_buffer_size -
    2843            0 :                        (transport_header_size + transport_tail_size));
    2844              :     }
    2845          101 :     if ((context->local_context.capability.sender_data_transfer_size != 0) &&
    2846            1 :         (context->local_context.capability.sender_data_transfer_size ==
    2847            1 :          context->sender_buffer_size)) {
    2848            0 :         context->local_context.capability.sender_data_transfer_size =
    2849            0 :             (uint32_t)(context->sender_buffer_size -
    2850            0 :                        (transport_header_size + transport_tail_size));
    2851              :     }
    2852              : 
    2853          101 :     context->local_context.capability.max_spdm_msg_size = max_spdm_msg_size;
    2854          101 :     context->local_context.capability.transport_header_size = transport_header_size;
    2855          101 :     context->local_context.capability.transport_tail_size = transport_tail_size;
    2856          101 :     context->transport_encode_message = transport_encode_message;
    2857          101 :     context->transport_decode_message = transport_decode_message;
    2858          101 : }
    2859              : 
    2860              : /**
    2861              :  * Register SPDM certificate verification functions for SPDM GET_CERTIFICATE in requester or responder.
    2862              :  * It is called after GET_CERTIFICATE gets a full certificate chain from peer.
    2863              :  *
    2864              :  * If it is NOT registered, the default verification in SPDM lib will be used. It verifies:
    2865              :  *    1) The integrity of the certificate chain, (Root Cert Hash->Root Cert->Cert Chain), according to X.509.
    2866              :  *  2) The trust anchor, according LIBSPDM_DATA_PEER_PUBLIC_ROOT_CERT or LIBSPDM_DATA_PEER_PUBLIC_CERT_CHAIN.
    2867              :  * If it is registered, SPDM lib will use this function to verify the certificate.
    2868              :  *
    2869              :  * This function must be called after libspdm_init_context, and before any SPDM communication.
    2870              :  *
    2871              :  * @param  context                  A pointer to the SPDM context.
    2872              :  * @param  verify_spdm_cert_chain   The function to verify an SPDM certificate after GET_CERTIFICATE.
    2873              :  **/
    2874            0 : void libspdm_register_verify_spdm_cert_chain_func(
    2875              :     void *spdm_context,
    2876              :     const libspdm_verify_spdm_cert_chain_func verify_spdm_cert_chain)
    2877              : {
    2878              :     libspdm_context_t *context;
    2879              : 
    2880            0 :     context = spdm_context;
    2881            0 :     context->local_context.verify_peer_spdm_cert_chain = verify_spdm_cert_chain;
    2882            0 : }
    2883              : 
    2884              : /**
    2885              :  * Get the size of required scratch buffer.
    2886              :  *
    2887              :  * The SPDM Integrator must call libspdm_get_sizeof_required_scratch_buffer to get the size,
    2888              :  * then allocate enough scratch buffer and call libspdm_set_scratch_buffer().
    2889              :  *
    2890              :  * @param  context                  A pointer to the SPDM context.
    2891              :  *
    2892              :  * @return the size of required scratch buffer.
    2893              :  **/
    2894          103 : size_t libspdm_get_sizeof_required_scratch_buffer (void *spdm_context)
    2895              : {
    2896              :     libspdm_context_t *context;
    2897              :     size_t scratch_buffer_size;
    2898              : 
    2899          103 :     context = spdm_context;
    2900          103 :     LIBSPDM_ASSERT (context->local_context.capability.max_spdm_msg_size != 0);
    2901              : 
    2902          103 :     scratch_buffer_size = libspdm_get_scratch_buffer_capacity(context);
    2903          103 :     return scratch_buffer_size;
    2904              : }
    2905              : 
    2906              : /**
    2907              :  * Set the scratch buffer.
    2908              :  *
    2909              :  * This function must be called after libspdm_init_context, and before any SPDM communication.
    2910              :  *
    2911              :  * @param  context                  A pointer to the SPDM context.
    2912              :  * @param  scratch_buffer           Buffer address of the scratch buffer.
    2913              :  * @param  scratch_buffer_size      Size of the scratch buffer.
    2914              :  *
    2915              :  **/
    2916          103 : void libspdm_set_scratch_buffer (
    2917              :     void *spdm_context,
    2918              :     void *scratch_buffer,
    2919              :     size_t scratch_buffer_size)
    2920              : {
    2921              :     libspdm_context_t *context;
    2922              : 
    2923          103 :     context = spdm_context;
    2924          103 :     LIBSPDM_ASSERT (context->local_context.capability.max_spdm_msg_size != 0);
    2925          103 :     LIBSPDM_ASSERT (scratch_buffer_size >= libspdm_get_scratch_buffer_capacity(spdm_context));
    2926          103 :     context->scratch_buffer = scratch_buffer;
    2927          103 :     context->scratch_buffer_size = scratch_buffer_size;
    2928          103 :     context->last_spdm_request = (uint8_t *)scratch_buffer +
    2929          103 :                                  libspdm_get_scratch_buffer_last_spdm_request_offset(spdm_context);
    2930              : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
    2931          103 :     context->cache_spdm_request = (uint8_t *)scratch_buffer +
    2932          103 :                                   libspdm_get_scratch_buffer_cache_spdm_request_offset(spdm_context);
    2933              : #endif
    2934          103 : }
    2935              : 
    2936              : /**
    2937              :  * Get the scratch buffer.
    2938              :  *
    2939              :  * @param  context                  A pointer to the SPDM context.
    2940              :  * @param  scratch_buffer           Buffer address of the scratch buffer.
    2941              :  * @param  scratch_buffer_size      Size of the scratch buffer.
    2942              :  *
    2943              :  **/
    2944       136626 : void libspdm_get_scratch_buffer (
    2945              :     void *spdm_context,
    2946              :     void **scratch_buffer,
    2947              :     size_t *scratch_buffer_size)
    2948              : {
    2949              :     libspdm_context_t *context;
    2950              : 
    2951       136626 :     context = spdm_context;
    2952       136626 :     LIBSPDM_ASSERT (context->scratch_buffer != NULL);
    2953       136626 :     LIBSPDM_ASSERT (context->scratch_buffer_size >=
    2954              :                     libspdm_get_scratch_buffer_capacity(spdm_context));
    2955       136626 :     *scratch_buffer = context->scratch_buffer;
    2956       136626 :     *scratch_buffer_size = context->scratch_buffer_size;
    2957              :     /* need to remove last 2 sections, because they are for libspdm internal state track. */
    2958       136626 :     *scratch_buffer_size -= libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context);
    2959              : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
    2960       136626 :     *scratch_buffer_size -= libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context);
    2961              : #endif
    2962       136626 : }
    2963              : 
    2964              : /**
    2965              :  * Acquire a device sender buffer for transport layer message.
    2966              :  *
    2967              :  * @param  context                       A pointer to the SPDM context.
    2968              :  * @param  msg_buf_ptr                   A pointer to a sender buffer.
    2969              :  *
    2970              :  * @retval RETURN_SUCCESS               The sender buffer is acquired.
    2971              :  **/
    2972         2575 : libspdm_return_t libspdm_acquire_sender_buffer (
    2973              :     libspdm_context_t *spdm_context, size_t *max_msg_size, void **msg_buf_ptr)
    2974              : {
    2975              :     libspdm_return_t status;
    2976              : 
    2977         2575 :     LIBSPDM_ASSERT (spdm_context->sender_buffer == NULL);
    2978         2575 :     LIBSPDM_ASSERT (spdm_context->sender_buffer_size != 0);
    2979         2575 :     status = spdm_context->acquire_sender_buffer (spdm_context, msg_buf_ptr);
    2980         2575 :     if (status != LIBSPDM_STATUS_SUCCESS) {
    2981            6 :         return status;
    2982              :     }
    2983         2569 :     spdm_context->sender_buffer = *msg_buf_ptr;
    2984         2569 :     *max_msg_size = spdm_context->sender_buffer_size;
    2985              :     #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
    2986              :     /* it return scratch buffer, because the requester need build message there.*/
    2987         5138 :     *msg_buf_ptr = (uint8_t *)spdm_context->scratch_buffer +
    2988         2569 :                    libspdm_get_scratch_buffer_large_sender_receiver_offset(spdm_context);
    2989         2569 :     *max_msg_size = libspdm_get_scratch_buffer_large_sender_receiver_capacity(spdm_context);
    2990              :     #endif
    2991         2569 :     return LIBSPDM_STATUS_SUCCESS;
    2992              : }
    2993              : 
    2994              : /**
    2995              :  * Release a device sender buffer for transport layer message.
    2996              :  *
    2997              :  * @param  context                       A pointer to the SPDM context.
    2998              :  *
    2999              :  * @retval RETURN_SUCCESS               The sender buffer is Released.
    3000              :  **/
    3001         2569 : void libspdm_release_sender_buffer (libspdm_context_t *spdm_context)
    3002              : {
    3003         2569 :     LIBSPDM_ASSERT(spdm_context->sender_buffer != NULL);
    3004         2569 :     LIBSPDM_ASSERT(spdm_context->sender_buffer_size != 0);
    3005              : 
    3006         2569 :     spdm_context->release_sender_buffer (spdm_context, spdm_context->sender_buffer);
    3007         2569 :     spdm_context->sender_buffer = NULL;
    3008         2569 : }
    3009              : 
    3010              : /**
    3011              :  * Get the sender buffer.
    3012              :  *
    3013              :  * @param  context                  A pointer to the SPDM context.
    3014              :  * @param  receiver_buffer            Buffer address of the sender buffer.
    3015              :  * @param  receiver_buffer_size       Size of the sender buffer.
    3016              :  *
    3017              :  **/
    3018        68170 : void libspdm_get_sender_buffer (
    3019              :     libspdm_context_t *spdm_context,
    3020              :     void **sender_buffer,
    3021              :     size_t *sender_buffer_size)
    3022              : {
    3023        68170 :     *sender_buffer = spdm_context->sender_buffer;
    3024        68170 :     *sender_buffer_size = spdm_context->sender_buffer_size;
    3025        68170 : }
    3026              : 
    3027              : /**
    3028              :  * Acquire a device receiver buffer for transport layer message.
    3029              :  *
    3030              :  * @param  context                       A pointer to the SPDM context.
    3031              :  * @param  max_msg_size                  size in bytes of the maximum size of receiver buffer.
    3032              :  * @param  msg_buf_pt                    A pointer to a receiver buffer.
    3033              :  *
    3034              :  * @retval RETURN_SUCCESS               The receiver buffer is acquired.
    3035              :  **/
    3036         2532 : libspdm_return_t libspdm_acquire_receiver_buffer (
    3037              :     libspdm_context_t *spdm_context, size_t *max_msg_size, void **msg_buf_ptr)
    3038              : {
    3039              :     libspdm_return_t status;
    3040              : 
    3041         2532 :     LIBSPDM_ASSERT (spdm_context->receiver_buffer == NULL);
    3042         2532 :     LIBSPDM_ASSERT (spdm_context->receiver_buffer_size != 0);
    3043         2532 :     status = spdm_context->acquire_receiver_buffer (spdm_context, msg_buf_ptr);
    3044         2532 :     if (status != LIBSPDM_STATUS_SUCCESS) {
    3045            6 :         return status;
    3046              :     }
    3047         2526 :     spdm_context->receiver_buffer = *msg_buf_ptr;
    3048         2526 :     *max_msg_size = spdm_context->receiver_buffer_size;
    3049              :     #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
    3050              :     /* it return scratch buffer, because the requester need build message there.*/
    3051         5052 :     *msg_buf_ptr = (uint8_t *)spdm_context->scratch_buffer +
    3052         2526 :                    libspdm_get_scratch_buffer_large_sender_receiver_offset(spdm_context);
    3053         2526 :     *max_msg_size = libspdm_get_scratch_buffer_large_sender_receiver_capacity(spdm_context);
    3054              :     #endif
    3055         2526 :     return LIBSPDM_STATUS_SUCCESS;
    3056              : }
    3057              : 
    3058              : /**
    3059              :  * Release a device receiver buffer for transport layer message.
    3060              :  *
    3061              :  * @param  context                       A pointer to the SPDM context.
    3062              :  *
    3063              :  * @retval RETURN_SUCCESS               The receiver buffer is Released.
    3064              :  **/
    3065         2526 : void libspdm_release_receiver_buffer (libspdm_context_t *spdm_context)
    3066              : {
    3067         2526 :     LIBSPDM_ASSERT(spdm_context->receiver_buffer != NULL);
    3068         2526 :     LIBSPDM_ASSERT(spdm_context->receiver_buffer_size != 0);
    3069              : 
    3070         2526 :     spdm_context->release_receiver_buffer (spdm_context, spdm_context->receiver_buffer);
    3071         2526 :     spdm_context->receiver_buffer = NULL;
    3072         2526 : }
    3073              : 
    3074              : /**
    3075              :  * Get the receiver buffer.
    3076              :  *
    3077              :  * @param  context                  A pointer to the SPDM context.
    3078              :  * @param  receiver_buffer            Buffer address of the receiver buffer.
    3079              :  * @param  receiver_buffer_size       Size of the receiver buffer.
    3080              :  *
    3081              :  **/
    3082            0 : void libspdm_get_receiver_buffer (
    3083              :     libspdm_context_t *spdm_context,
    3084              :     void **receiver_buffer,
    3085              :     size_t *receiver_buffer_size)
    3086              : {
    3087            0 :     *receiver_buffer = spdm_context->receiver_buffer;
    3088            0 :     *receiver_buffer_size = spdm_context->receiver_buffer_size;
    3089            0 : }
    3090              : 
    3091              : /**
    3092              :  * Get the last SPDM error struct of an SPDM context.
    3093              :  *
    3094              :  * @param  spdm_context                  A pointer to the SPDM context.
    3095              :  * @param  last_spdm_error                Last SPDM error struct of an SPDM context.
    3096              :  */
    3097            0 : void libspdm_get_last_spdm_error_struct(void *spdm_context, libspdm_error_struct_t *last_spdm_error)
    3098              : {
    3099              :     libspdm_context_t *context;
    3100              : 
    3101            0 :     context = spdm_context;
    3102            0 :     libspdm_copy_mem(last_spdm_error, sizeof(libspdm_error_struct_t),
    3103            0 :                      &context->last_spdm_error,sizeof(libspdm_error_struct_t));
    3104            0 : }
    3105              : 
    3106              : /**
    3107              :  * Set the last SPDM error struct of an SPDM context.
    3108              :  *
    3109              :  * @param  spdm_context                  A pointer to the SPDM context.
    3110              :  * @param  last_spdm_error                Last SPDM error struct of an SPDM context.
    3111              :  */
    3112        68264 : void libspdm_set_last_spdm_error_struct(void *spdm_context, libspdm_error_struct_t *last_spdm_error)
    3113              : {
    3114              :     libspdm_context_t *context;
    3115              : 
    3116        68264 :     context = spdm_context;
    3117        68264 :     libspdm_copy_mem(&context->last_spdm_error, sizeof(context->last_spdm_error),
    3118              :                      last_spdm_error, sizeof(libspdm_error_struct_t));
    3119        68264 : }
    3120              : 
    3121              : #if LIBSPDM_FIPS_MODE
    3122              : /**
    3123              :  * Initialize an libspdm_fips_selftest_context.
    3124              :  *
    3125              :  * @param  fips_selftest_context       A pointer to the fips_selftest_context.
    3126              :  *
    3127              :  * @retval RETURN_SUCCESS       context is initialized.
    3128              :  * @retval RETURN_DEVICE_ERROR  context initialization failed.
    3129              :  */
    3130            0 : libspdm_return_t libspdm_init_fips_selftest_context(void *fips_selftest_context)
    3131              : {
    3132              :     libspdm_fips_selftest_context_t *context;
    3133            0 :     LIBSPDM_ASSERT(fips_selftest_context != NULL);
    3134              : 
    3135            0 :     context = fips_selftest_context;
    3136              : 
    3137              :     /*No tested for every used algo*/
    3138            0 :     context->tested_algo = 0;
    3139              :     /*self_test result is false for every used algo*/
    3140            0 :     context->self_test_result = 0;
    3141              : 
    3142            0 :     return LIBSPDM_STATUS_SUCCESS;
    3143              : }
    3144              : 
    3145              : /**
    3146              :  * Return the size in bytes of the fips_selftest_context.
    3147              :  *
    3148              :  * @return the size in bytes of the fips_selftest_context.
    3149              :  **/
    3150            0 : size_t libspdm_get_fips_selftest_context_size(void)
    3151              : {
    3152              :     size_t size;
    3153              : 
    3154            0 :     size = sizeof(libspdm_fips_selftest_context_t);
    3155            0 :     return size;
    3156              : }
    3157              : 
    3158              : /**
    3159              :  * import fips_selftest_context to spdm_context;
    3160              :  *
    3161              :  * @param[in,out]  spdm_context                A pointer to the spdm_context.
    3162              :  * @param[in]      fips_selftest_context       A pointer to the fips_selftest_context.
    3163              :  * @param[in]      fips_selftest_context_size  The size of fips_selftest_context.
    3164              :  *
    3165              :  * @retval true   import fips_selftest_context successful.
    3166              :  * @retval false  spdm_context or fips_selftest_context is null.
    3167              :  */
    3168            0 : bool libspdm_import_fips_selftest_context_to_spdm_context(void *spdm_context,
    3169              :                                                           void *fips_selftest_context,
    3170              :                                                           size_t fips_selftest_context_size)
    3171              : {
    3172              :     libspdm_fips_selftest_context_t *libspdm_fips_selftest_context;
    3173              :     libspdm_context_t *libspdm_context;
    3174              : 
    3175            0 :     libspdm_context = spdm_context;
    3176            0 :     libspdm_fips_selftest_context = fips_selftest_context;
    3177              : 
    3178            0 :     if ((libspdm_context == NULL) || (libspdm_fips_selftest_context == NULL)) {
    3179            0 :         return false;
    3180              :     }
    3181            0 :     if (fips_selftest_context_size != sizeof(libspdm_fips_selftest_context_t)) {
    3182            0 :         return false;
    3183              :     }
    3184              : 
    3185            0 :     libspdm_copy_mem(&(libspdm_context->fips_selftest_context),
    3186              :                      sizeof(libspdm_fips_selftest_context_t),
    3187              :                      libspdm_fips_selftest_context, sizeof(libspdm_fips_selftest_context_t));
    3188            0 :     return true;
    3189              : }
    3190              : 
    3191              : /**
    3192              :  * export fips_selftest_context from spdm_context;
    3193              :  *
    3194              :  * @param[in]          spdm_context                A pointer to the spdm_context.
    3195              :  * @param[in,out]      fips_selftest_context       A pointer to the fips_selftest_context.
    3196              :  * @param[in]          fips_selftest_context_size  The size of fips_selftest_context.
    3197              :  *
    3198              :  * @retval true   export fips_selftest_context successful.
    3199              :  * @retval false  spdm_context or fips_selftest_context is null.
    3200              :  */
    3201            0 : bool libspdm_export_fips_selftest_context_from_spdm_context(void *spdm_context,
    3202              :                                                             void *fips_selftest_context,
    3203              :                                                             size_t fips_selftest_context_size)
    3204              : {
    3205              :     libspdm_fips_selftest_context_t *libspdm_fips_selftest_context;
    3206              :     libspdm_context_t *libspdm_context;
    3207              : 
    3208            0 :     libspdm_context = spdm_context;
    3209            0 :     libspdm_fips_selftest_context = fips_selftest_context;
    3210              : 
    3211            0 :     if ((libspdm_context == NULL) || (libspdm_fips_selftest_context == NULL)) {
    3212            0 :         return false;
    3213              :     }
    3214            0 :     if (fips_selftest_context_size != sizeof(libspdm_fips_selftest_context_t)) {
    3215            0 :         return false;
    3216              :     }
    3217              : 
    3218            0 :     libspdm_copy_mem(libspdm_fips_selftest_context,
    3219              :                      sizeof(libspdm_fips_selftest_context_t),
    3220            0 :                      &(libspdm_context->fips_selftest_context),
    3221              :                      sizeof(libspdm_fips_selftest_context_t));
    3222            0 :     return true;
    3223              : }
    3224              : 
    3225              : #endif /* LIBSPDM_FIPS_MODE */
    3226              : 
    3227              : /**
    3228              :  * Initialize an SPDM context, as well as all secured message contexts,
    3229              :  * in the specified locations.
    3230              :  *
    3231              :  * The size in bytes of the spdm_context can be returned by
    3232              :  * libspdm_get_context_size_without_secured_context.
    3233              :  *
    3234              :  * The size in bytes of a single secured message context can be returned by
    3235              :  * libspdm_secured_message_get_context_size.
    3236              :  *
    3237              :  * @param  spdm_context          A pointer to the SPDM context.
    3238              :  * @param  secured_contexts      An array of pointers, with each entry containing
    3239              :  *                               the location of a secured message context.
    3240              :  * @param  num_secured_contexts  Number of secured message contexts to initialize.
    3241              :  *                               Currently, only LIBSPDM_MAX_SESSION_COUNT is supported.
    3242              :  *
    3243              :  * @retval RETURN_SUCCESS        Contexts are initialized.
    3244              :  * @retval RETURN_DEVICE_ERROR   Context initialization failed.
    3245              :  */
    3246          107 : libspdm_return_t libspdm_init_context_with_secured_context(void *spdm_context,
    3247              :                                                            void **secured_contexts,
    3248              :                                                            size_t num_secured_contexts)
    3249              : {
    3250              :     libspdm_context_t *context;
    3251              :     size_t index;
    3252              : 
    3253          107 :     LIBSPDM_ASSERT(spdm_context != NULL);
    3254          107 :     LIBSPDM_ASSERT(secured_contexts != NULL);
    3255          107 :     LIBSPDM_ASSERT(num_secured_contexts == LIBSPDM_MAX_SESSION_COUNT);
    3256              : 
    3257          107 :     context = spdm_context;
    3258          107 :     libspdm_zero_mem(context, sizeof(libspdm_context_t));
    3259          107 :     context->version = LIBSPDM_CONTEXT_STRUCT_VERSION;
    3260          107 :     context->transcript.message_a.max_buffer_size =
    3261              :         sizeof(context->transcript.message_a.buffer);
    3262          107 :     context->transcript.message_d.max_buffer_size =
    3263              :         sizeof(context->transcript.message_d.buffer);
    3264              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3265              :     context->transcript.message_b.max_buffer_size =
    3266              :         sizeof(context->transcript.message_b.buffer);
    3267              :     context->transcript.message_c.max_buffer_size =
    3268              :         sizeof(context->transcript.message_c.buffer);
    3269              :     context->transcript.message_mut_b.max_buffer_size =
    3270              :         sizeof(context->transcript.message_mut_b.buffer);
    3271              :     context->transcript.message_mut_c.max_buffer_size =
    3272              :         sizeof(context->transcript.message_mut_c.buffer);
    3273              :     context->transcript.message_m.max_buffer_size =
    3274              :         sizeof(context->transcript.message_m.buffer);
    3275              :     context->transcript.message_e.max_buffer_size =
    3276              :         sizeof(context->transcript.message_e.buffer);
    3277              :     context->transcript.message_encap_e.max_buffer_size =
    3278              :         sizeof(context->transcript.message_encap_e.buffer);
    3279              : #endif
    3280          107 :     context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
    3281          107 :     context->local_context.version.spdm_version_count = SPDM_MAX_VERSION_COUNT;
    3282          107 :     context->local_context.version.spdm_version[0] = SPDM_MESSAGE_VERSION_10 <<
    3283              :                                                      SPDM_VERSION_NUMBER_SHIFT_BIT;
    3284          107 :     context->local_context.version.spdm_version[1] = SPDM_MESSAGE_VERSION_11 <<
    3285              :                                                      SPDM_VERSION_NUMBER_SHIFT_BIT;
    3286          107 :     context->local_context.version.spdm_version[2] = SPDM_MESSAGE_VERSION_12 <<
    3287              :                                                      SPDM_VERSION_NUMBER_SHIFT_BIT;
    3288          107 :     context->local_context.version.spdm_version[3] = SPDM_MESSAGE_VERSION_13 <<
    3289              :                                                      SPDM_VERSION_NUMBER_SHIFT_BIT;
    3290          107 :     context->local_context.secured_message_version.spdm_version_count =
    3291              :         SECURED_SPDM_MAX_VERSION_COUNT;
    3292          107 :     context->local_context.secured_message_version.spdm_version[0] =
    3293              :         SECURED_SPDM_VERSION_10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
    3294          107 :     context->local_context.secured_message_version.spdm_version[1] =
    3295              :         SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
    3296          107 :     context->local_context.secured_message_version.spdm_version[2] =
    3297              :         SECURED_SPDM_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT;
    3298          107 :     context->local_context.capability.st1 = SPDM_ST1_VALUE_US;
    3299              : 
    3300          107 :     context->mut_auth_cert_chain_buffer_size = 0;
    3301              : 
    3302          107 :     context->max_spdm_session_sequence_number = LIBSPDM_MAX_SPDM_SESSION_SEQUENCE_NUMBER;
    3303              : 
    3304          107 :     context->latest_session_id = INVALID_SESSION_ID;
    3305          107 :     context->last_spdm_request_session_id = INVALID_SESSION_ID;
    3306          107 :     context->last_spdm_request_session_id_valid = false;
    3307          107 :     context->last_spdm_request_size = 0;
    3308              : 
    3309              :     /* To be updated in libspdm_register_device_buffer_func */
    3310          107 :     context->local_context.capability.data_transfer_size = 0;
    3311          107 :     context->local_context.capability.sender_data_transfer_size = 0;
    3312          107 :     context->local_context.capability.max_spdm_msg_size = 0;
    3313              : 
    3314          535 :     for (index = 0; index < num_secured_contexts; index++) {
    3315          428 :         if (secured_contexts[index] == NULL) {
    3316            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    3317              :         }
    3318              : 
    3319          428 :         context->session_info[index].secured_message_context = secured_contexts[index];
    3320          428 :         libspdm_secured_message_init_context(
    3321              :             context->session_info[index].secured_message_context);
    3322              :     }
    3323              : 
    3324          107 :     return LIBSPDM_STATUS_SUCCESS;
    3325              : }
    3326              : 
    3327              : /**
    3328              :  * Initialize an SPDM context, as well as secured message contexts.
    3329              :  * The secured message contexts are appended to the context structure.
    3330              :  *
    3331              :  * The total size in bytes of the spdm_context and all secured message
    3332              :  * contexts can be returned by libspdm_get_context_size().
    3333              :  *
    3334              :  * @param  spdm_context         A pointer to the SPDM context.
    3335              :  *
    3336              :  * @retval RETURN_SUCCESS       context is initialized.
    3337              :  * @retval RETURN_DEVICE_ERROR  context initialization failed.
    3338              :  */
    3339          106 : libspdm_return_t libspdm_init_context(void *spdm_context)
    3340              : {
    3341              :     libspdm_context_t *context;
    3342              :     void *secured_context;
    3343              :     void *secured_contexts[LIBSPDM_MAX_SESSION_COUNT];
    3344              :     size_t secured_context_size;
    3345              :     size_t index;
    3346              : 
    3347          106 :     LIBSPDM_ASSERT(spdm_context != NULL);
    3348              : 
    3349              :     /* libspdm_get_context_size() allocates space for all secured message
    3350              :      * contexts. They are appended to the general SPDM context. */
    3351          106 :     context = spdm_context;
    3352          106 :     secured_context = (void *)((size_t)(context + 1));
    3353          106 :     secured_context_size = libspdm_secured_message_get_context_size();
    3354              : 
    3355          530 :     for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++)
    3356              :     {
    3357          424 :         secured_contexts[index] = (uint8_t *)secured_context + secured_context_size * index;
    3358              :     }
    3359              : 
    3360          106 :     return libspdm_init_context_with_secured_context(spdm_context,
    3361              :                                                      secured_contexts,
    3362              :                                                      LIBSPDM_MAX_SESSION_COUNT);
    3363              : }
    3364              : 
    3365           42 : void libspdm_reset_context(void *spdm_context)
    3366              : {
    3367              :     libspdm_context_t *context;
    3368              :     size_t index;
    3369              : 
    3370           42 :     context = spdm_context;
    3371              : 
    3372              :     /*Clear all info about last connection*/
    3373              : 
    3374              :     /*need clear session info to free context before algo is zeroed.*/
    3375          210 :     for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++)
    3376              :     {
    3377          168 :         libspdm_session_info_init(context,
    3378              :                                   &context->session_info[index],
    3379              :                                   INVALID_SESSION_ID,
    3380              :                                   false);
    3381              :     }
    3382              : 
    3383           42 :     context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NOT_STARTED;
    3384           42 :     libspdm_zero_mem(&context->connection_info.version, sizeof(spdm_version_number_t));
    3385           42 :     libspdm_zero_mem(&context->connection_info.capability,
    3386              :                      sizeof(libspdm_device_capability_t));
    3387           42 :     libspdm_zero_mem(&context->connection_info.algorithm, sizeof(libspdm_device_algorithm_t));
    3388           42 :     libspdm_zero_mem(&context->last_spdm_error, sizeof(libspdm_error_struct_t));
    3389           42 :     libspdm_zero_mem(&context->encap_context, sizeof(libspdm_encap_context_t));
    3390           42 :     context->connection_info.local_used_cert_chain_buffer_size = 0;
    3391           42 :     context->connection_info.local_used_cert_chain_buffer = NULL;
    3392           42 :     context->connection_info.multi_key_conn_req = false;
    3393           42 :     context->connection_info.multi_key_conn_rsp = false;
    3394              : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
    3395           42 :     context->cache_spdm_request_size = 0;
    3396              : #endif
    3397           42 :     context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
    3398           42 :     context->current_token = 0;
    3399           42 :     context->latest_session_id = INVALID_SESSION_ID;
    3400           42 :     context->last_spdm_request_session_id = INVALID_SESSION_ID;
    3401           42 :     context->last_spdm_request_session_id_valid = false;
    3402           42 :     context->last_spdm_request_size = 0;
    3403           42 :     context->mut_auth_cert_chain_buffer_size = 0;
    3404           42 :     context->current_dhe_session_count = 0;
    3405           42 :     context->current_psk_session_count = 0;
    3406           42 : }
    3407              : 
    3408              : /**
    3409              :  * Free the memory of contexts within the SPDM context.
    3410              :  * These are typically contexts whose memory has been allocated by the cryptography library.
    3411              :  * This function does not free the SPDM context itself.
    3412              :  *
    3413              :  * @param[in]  spdm_context         A pointer to the SPDM context.
    3414              :  *
    3415              :  */
    3416            0 : void libspdm_deinit_context(void *spdm_context)
    3417              : {
    3418              :     uint32_t session_id;
    3419              :     libspdm_context_t *context;
    3420              :     libspdm_session_info_t *session_info;
    3421              : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT)
    3422              :     void *pubkey_context;
    3423              :     bool is_requester;
    3424              :     uint8_t slot_index;
    3425              : #endif
    3426              : 
    3427            0 :     context = spdm_context;
    3428              : 
    3429              : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT)
    3430            0 :     is_requester = context->local_context.is_requester;
    3431              : 
    3432            0 :     for (slot_index = 0; slot_index < SPDM_MAX_SLOT_COUNT; slot_index++) {
    3433            0 :         pubkey_context = context->connection_info.peer_used_cert_chain[slot_index].
    3434              :                          leaf_cert_public_key;
    3435              : 
    3436            0 :         if (pubkey_context != NULL) {
    3437            0 :             if (is_requester) {
    3438            0 :                 libspdm_asym_free(
    3439              :                     context->connection_info.algorithm.base_asym_algo, pubkey_context);
    3440              :             } else {
    3441            0 :                 libspdm_req_asym_free(
    3442            0 :                     context->connection_info.algorithm.req_base_asym_alg, pubkey_context);
    3443              :             }
    3444              : 
    3445            0 :             context->connection_info.peer_used_cert_chain[slot_index].leaf_cert_public_key = NULL;
    3446              :         }
    3447              :     }
    3448              : #endif
    3449              : 
    3450            0 :     libspdm_reset_message_a(context);
    3451            0 :     libspdm_reset_message_d(context);
    3452            0 :     libspdm_reset_message_b(context);
    3453            0 :     libspdm_reset_message_c(context);
    3454            0 :     libspdm_reset_message_mut_b(context);
    3455            0 :     libspdm_reset_message_mut_c(context);
    3456            0 :     for (session_id = 0; session_id < LIBSPDM_MAX_SESSION_COUNT; session_id++) {
    3457            0 :         session_info = &context->session_info[session_id];
    3458            0 :         libspdm_reset_message_m(context, session_info);
    3459            0 :         libspdm_reset_message_e(context, session_info);
    3460            0 :         libspdm_reset_message_encap_e(context, session_info);
    3461            0 :         libspdm_reset_message_encap_d(context, session_info);
    3462            0 :         libspdm_reset_message_k(context, session_info);
    3463            0 :         libspdm_reset_message_f(context, session_info);
    3464              :     }
    3465            0 : }
    3466              : 
    3467              : /**
    3468              :  * Return the size in bytes of the SPDM context. This includes all
    3469              :  * secured message context data as well.
    3470              :  *
    3471              :  * For just the SPDM context size, use libspdm_get_context_size_without_secured_context.
    3472              :  *
    3473              :  * @return the size in bytes of the SPDM context and secured message contexts.
    3474              :  **/
    3475          106 : size_t libspdm_get_context_size(void)
    3476              : {
    3477              :     size_t size;
    3478              : 
    3479          106 :     size = sizeof(libspdm_context_t) +
    3480          106 :            libspdm_secured_message_get_context_size() * LIBSPDM_MAX_SESSION_COUNT;
    3481          106 :     LIBSPDM_ASSERT (size == LIBSPDM_CONTEXT_SIZE_ALL);
    3482          106 :     return size;
    3483              : }
    3484              : 
    3485              : /**
    3486              :  * Return the size in bytes of just the SPDM context, without secured message context.
    3487              :  *
    3488              :  * For the complete context size, use libspdm_get_context_size.
    3489              :  *
    3490              :  * @return the size in bytes of the SPDM context.
    3491              :  **/
    3492            1 : size_t libspdm_get_context_size_without_secured_context(void)
    3493              : {
    3494              :     size_t size;
    3495              : 
    3496            1 :     size = sizeof(libspdm_context_t);
    3497            1 :     LIBSPDM_ASSERT (size == LIBSPDM_CONTEXT_SIZE_WITHOUT_SECURED_CONTEXT);
    3498            1 :     return size;
    3499              : }
    3500              : 
    3501              : /**
    3502              :  * Return the SPDMversion field of the version number struct.
    3503              :  *
    3504              :  * @param  ver                Spdm version number struct.
    3505              :  *
    3506              :  * @return the SPDMversion of the version number struct.
    3507              :  **/
    3508          229 : uint8_t libspdm_get_version_from_version_number(const spdm_version_number_t ver)
    3509              : {
    3510          229 :     return (uint8_t)(ver >> SPDM_VERSION_NUMBER_SHIFT_BIT);
    3511              : }
    3512              : 
    3513              : /**
    3514              :  * Sort SPDMversion in descending order.
    3515              :  *
    3516              :  * @param  spdm_context                A pointer to the SPDM context.
    3517              :  * @param  ver_set                    A pointer to the version set.
    3518              :  * @param  ver_num                    Version number.
    3519              :  */
    3520           60 : void libspdm_version_number_sort(spdm_version_number_t *ver_set, size_t ver_num)
    3521              : {
    3522              :     size_t index;
    3523              :     size_t index_sort;
    3524              :     size_t index_max;
    3525              :     spdm_version_number_t version;
    3526              : 
    3527              :     /* Select sort */
    3528           60 :     if (ver_num > 1) {
    3529          131 :         for (index_sort = 0; index_sort < ver_num; index_sort++) {
    3530           99 :             index_max = index_sort;
    3531          210 :             for (index = index_sort + 1; index < ver_num; index++) {
    3532              :                 /* if ver_ser[index] higher than ver_set[index_max] */
    3533          111 :                 if (ver_set[index] > ver_set[index_max]) {
    3534           66 :                     index_max = index;
    3535              :                 }
    3536              :             }
    3537              :             /* swap ver_ser[index_min] and ver_set[index_sort] */
    3538           99 :             version = ver_set[index_sort];
    3539           99 :             ver_set[index_sort] = ver_set[index_max];
    3540           99 :             ver_set[index_max] = version;
    3541              :         }
    3542              :     }
    3543           60 : }
    3544              : 
    3545              : /**
    3546              :  * Negotiate SPDMversion for connection.
    3547              :  * ver_set is the local version set of requester, res_ver_set is the version set of responder.
    3548              :  *
    3549              :  * @param  common_version             A pointer to store the common version.
    3550              :  * @param  req_ver_set                A pointer to the requester version set.
    3551              :  * @param  req_ver_num                Version number of requester.
    3552              :  * @param  res_ver_set                A pointer to the responder version set.
    3553              :  * @param  res_ver_num                Version number of responder.
    3554              :  *
    3555              :  * @retval true                       Negotiation successfully, connect version be saved to common_version.
    3556              :  * @retval false                      Negotiation failed.
    3557              :  */
    3558           30 : bool libspdm_negotiate_connection_version(spdm_version_number_t *common_version,
    3559              :                                           spdm_version_number_t *req_ver_set,
    3560              :                                           size_t req_ver_num,
    3561              :                                           const spdm_version_number_t *res_ver_set,
    3562              :                                           size_t res_ver_num)
    3563              : {
    3564              :     spdm_version_number_t req_version_list[LIBSPDM_MAX_VERSION_COUNT];
    3565              :     spdm_version_number_t res_version_list[LIBSPDM_MAX_VERSION_COUNT];
    3566              :     size_t req_index;
    3567              :     size_t res_index;
    3568              : 
    3569           30 :     if (req_ver_num > LIBSPDM_MAX_VERSION_COUNT || res_ver_num > LIBSPDM_MAX_VERSION_COUNT) {
    3570            0 :         return false;
    3571              :     }
    3572              : 
    3573           30 :     if (req_ver_set == NULL || req_ver_num == 0 || res_ver_set == NULL || res_ver_num == 0) {
    3574            0 :         return false;
    3575              :     }
    3576              : 
    3577           30 :     libspdm_zero_mem(req_version_list, sizeof(spdm_version_number_t) * LIBSPDM_MAX_VERSION_COUNT);
    3578           30 :     libspdm_zero_mem(res_version_list, sizeof(spdm_version_number_t) * LIBSPDM_MAX_VERSION_COUNT);
    3579              : 
    3580           30 :     libspdm_copy_mem(req_version_list, sizeof(spdm_version_number_t) * LIBSPDM_MAX_VERSION_COUNT,
    3581              :                      req_ver_set, sizeof(spdm_version_number_t) * req_ver_num);
    3582           30 :     libspdm_copy_mem(res_version_list, sizeof(spdm_version_number_t) * LIBSPDM_MAX_VERSION_COUNT,
    3583              :                      res_ver_set, sizeof(spdm_version_number_t) * res_ver_num);
    3584              : 
    3585              :     /* Sort SPDMversion in descending order. */
    3586           30 :     libspdm_version_number_sort(req_version_list, req_ver_num);
    3587           30 :     libspdm_version_number_sort(res_version_list, res_ver_num);
    3588              : 
    3589              :     /**
    3590              :      * Find highest same version and make req_index point to it.
    3591              :      * If not found, return false.
    3592              :      **/
    3593           35 :     for (res_index = 0; res_index < res_ver_num; res_index++) {
    3594           62 :         for (req_index = 0; req_index < req_ver_num; req_index++) {
    3595          114 :             if (libspdm_get_version_from_version_number(req_version_list[req_index]) ==
    3596           57 :                 libspdm_get_version_from_version_number(res_version_list[res_index])) {
    3597           29 :                 *common_version = req_version_list[req_index];
    3598           29 :                 return true;
    3599              :             }
    3600              :         }
    3601              :     }
    3602            1 :     return false;
    3603              : }
    3604              : 
    3605              : #if LIBSPDM_EVENT_RECIPIENT_SUPPORT
    3606            8 : void libspdm_register_event_callback(void *context,
    3607              :                                      libspdm_process_event_func process_event_func)
    3608              : {
    3609              :     libspdm_context_t *spdm_context;
    3610              : 
    3611            8 :     spdm_context = context;
    3612            8 :     spdm_context->process_event = process_event_func;
    3613            8 : }
    3614              : #endif /* LIBSPDM_EVENT_RECIPIENT_SUPPORT */
        

Generated by: LCOV version 2.0-1