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.2 % 1690 764
Test Date: 2026-08-16 08:12:25 Functions: 84.6 % 78 66

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

Generated by: LCOV version 2.0-1